Vue 自定义ip地址输入组件

实现效果:

组件代码

javascript 复制代码
<template>
  <div class="ip-input flex flex-space-between flex-center-cz">
    <input type="text" v-model="value1" maxlength="3" ref="ip1" :placeholder="placeholder" @input="changeToNext1(value1)"/>
    ·
    <input type="text" v-model="value2" maxlength="3" ref="ip2" :placeholder="placeholder" @input="changeToNext2(value2)"/>
    ·
    <input type="text" v-model="value3" maxlength="3" ref="ip3" :placeholder="placeholder" @input="changeToNext3(value3)"/>
    ·
    <input type="text" v-model="value4" maxlength="3" ref="ip4" :placeholder="placeholder" @input="ipAddress"/>
  </div>
</template>

<script>
export default {
  name:'IPInput',
  props:{
    placeholder:{},
    ip: {}
  },
  model: {
    prop: "ip",
    event: "change"
  },
  created(){
  },
  watch:{
    ip: {
      handler(newVal) {
        let arr = newVal.split(".")
        if ( arr.length === 4 ) {
          this.value1 = arr[0]
          this.value2 = arr[1]
          this.value3 = arr[2]
          this.value4 = arr[3]
        }
        if ( newVal === "..." ) {
          this.$emit("change", '')
        }
      },
      deep: true
    }
  },
  mounted() {
    if (this.ip == null) return;
    let arr = this.ip.split(".")
    if ( arr.length === 4 ) {
      this.value1 = arr[0]
      this.value2 = arr[1]
      this.value3 = arr[2]
      this.value4 = arr[3]
      this.$emit("change", this.value1 + "." + this.value2 + "." + this.value3 + "." + this.value4)
    }
  },
  data() {
    return {
      value1: '',
      value2: '',
      value3: '',
      value4: '',
    }
  },
  methods:{
    ipAddress() {
      this.$emit("change", this.value1 + "." + this.value2 + "." + this.value3 + "." + this.value4);
    },
    changeToNext1(v) {
      if (v.toString().length === 3) {
        this.$nextTick(() => {
          this.$refs.ip2.focus();
        });
      }
      this.$emit("change", this.value1 + "." + this.value2 + "." + this.value3 + "." + this.value4);
    },
    changeToNext2(v) {
      if (v.toString().length === 3) {
        this.$nextTick(() => {
          this.$refs.ip3.focus();
        });
      }
      this.$emit("change", this.value1 + "." + this.value2 + "." + this.value3 + "." + this.value4);
    },
    changeToNext3(v) {
      if (v.toString().length === 3) {
        this.$nextTick(() => {
          this.$refs.ip4.focus();
        });
      }
      this.$emit("change", this.value1 + "." + this.value2 + "." + this.value3 + "." + this.value4);
    }
  }
}
</script>

<style scoped>

.ip-input {
  box-sizing: border-box;
  border: 1px solid #E1DCDC;
  height: 28px;
  background-color: #FFFFFF;
}
.ip-input input {
  border: 0;
  width: 100%;
  text-align: center;
}

</style>

组件使用代码

javascript 复制代码
<template>
  <div class="root flex flex-col border-box padding-l">
    <IpInput v-model="ip" style="width: 200px;"></IpInput>
  </div>
</template>

<script>
import IpInput from '@/components/input/IpInput.vue'

export default{
  name:'',
  created() {
  },
  components: {IpInput},
  data() {
    return {
      ip:null
    }
  },
  methods:{
  }
}
</script>
相关推荐
雨落Re1 小时前
从递归组件到 DSL 引擎:我造了一个让 AI 能"搭 UI"的运行时
前端·vue.js
codingWhat16 小时前
介绍一个手势识别库——AlloyFinger
前端·javascript·vue.js
踩着两条虫17 小时前
VTJ.PRO 双向代码转换原理揭秘
前端·vue.js·人工智能
SuperEugene21 小时前
Vue生态精选篇:Element Plus 的“企业后台常用组件”用法扫盲
前端·vue.js·面试
bluceli1 天前
Vue 3 Composition API深度解析:构建可复用逻辑的终极方案
前端·vue.js
程序员ys1 天前
前端权限控制设计
前端·vue.js·react.js
滕青山1 天前
腾讯域名拦截查询 在线工具核心JS实现
前端·javascript·vue.js
wuhen_n1 天前
TypeScript 强力护航:PropType 与组件事件类型的声明
前端·javascript·vue.js
wuhen_n1 天前
组件设计原则:如何设计一个高内聚、低耦合的 Vue 组件
前端·javascript·vue.js
独泪了无痕2 天前
Vue调试神器:Vue DevTools使用指南
vue.js·前端工程化