vue ip input 组件

<template>
  <ul class="ipAdress" :style="`width: ${width}px`">
    <li v-for="(item, index) in ipAddress" :key="index">
      <input
        ref="ipInput"
        v-model="item.value"
        type="text"
        class="ipInputClass"
        :style="`width: ${width / 4}px`"
        @input="checkIpVal(item)"
        @keyup="turnIpPosition(item, index, $event)"
      />
      <div></div>
    </li>
  </ul>
</template>

<script>
export default {
  props: {
    value: {
      type: String,
      default: "",
    },
    width: {
      type: Number,
      default: 200,
    },
  },
  data() {
    return {
      ipAddress: [
        {
          value: "",
        },
        {
          value: "",
        },
        {
          value: "",
        },
        {
          value: "",
        },
      ],
    };
  },
  watch: {
    ipAddress: {
      // 双向数据绑定的value
      handler: function (newVal) {
        let str = "";
        for (const i in newVal) {
          str += i == 0 ? `${newVal[i].value}` : `.${newVal[i].value}`;
        }
        // if (str === "0.0.0.0") {
        //   str = "";
        // }
        this.$emit("input", str);
      },
      deep: true,
    },
    value(newVal) {
      if (newVal) {
        this.ipAddress = newVal.split(".").map((e) => {
          e = { value: e };
          return e;
        });
      }
    },
  },
  methods: {
    // 格式化补零方法
    formatter(val) {
      let value = val.toString();
      if (value.length === 2) {
        value = "0" + value;
      } else if (value.length === 1) {
        value = "00" + value;
      } else if (value.length === 0) {
        value = "000";
      }
      return value;
    },
    // 检查ip输入为0-255
    checkIpVal(item) {
      //确保每个值都处于0-255
      let val = item.value;
      // 处理非数字
      val = val.toString().replace(/[^0-9]/g, "");
      val = parseInt(val, 10);
      if (isNaN(val)) {
        val = "";
      } else {
        val = val < 0 ? 0 : val;
        val = val > 255 ? 255 : val;
      }
      item.value = val;
    },
    // 光标位置判断
    turnIpPosition(item, index, event) {
      let self = this;
      let e = event || window.event;
      if (e.keyCode === 37) {
        // 左箭头向左跳转,左一不做任何措施
        if (index !== 0 && e.currentTarget.selectionStart === 0) {
          self.$refs.ipInput[index - 1].focus();
        }
      } else if (e.keyCode == 39) {
        // 右箭头向右跳转,右一不做任何措施
        if (
          index !== 3 &&
          e.currentTarget.selectionStart === item.value.toString().length
        ) {
          self.$refs.ipInput[index + 1].focus();
        }
      } else if (e.keyCode === 8) {
        // 删除键把当前数据删除完毕后会跳转到前一个input,左一不做任何处理
        if (index !== 0 && item.value === "") {
          self.$refs.ipInput[index - 1].focus();
        }
      } else if (
        e.keyCode === 13 ||
        e.keyCode === 32 ||
        e.keyCode === 190 ||
        e.keyCode === 110
      ) {
        // 回车键、空格键、冒号均向右跳转,右一不做任何措施
        if (index !== 3) {
          self.$refs.ipInput[index + 1].focus();
        }
      } else if (item.value.toString().length === 3) {
        // 满3位,光标自动向下一个文本框
        if (index !== 3) {
          self.$refs.ipInput[index + 1].focus();
        }
      }
    },
  },
};
</script>
<style type="text/css" scoped>
.ipAdress {
  display: flex;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  height: 34px;
  padding-inline-start: 0px;
}
.ipAdress li {
  position: relative;
  height: 34px;
  margin: 0;
  list-style-type: none;
}
.ipInputClass {
  border: none;
  height: 23px;
  text-align: center;
  background: transparent;
}
.ipAdress li div {
  position: absolute;
  bottom: 8px;
  right: 0;
  border-radius: 50%;
  background: #505050;
  width: 2px;
  height: 2px;
}
/*只需要3个div*/
.ipAdress li:last-child div {
  display: none;
}
/*取消掉默认的input focus状态*/
.ipAdress input:focus {
  outline: none;
}
</style>

转载https://blog.csdn.net/qq_36637705/article/details/100919922

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值