<template>
  <div>
    <div class="ipBox">
      <el-input
        @input="(e) => checkFormat(e, 'a')"
        placeholder="0-255"
        :maxlength="3"
        v-model="ip.a"
        size="small"
        @blur="blur"
        ref="ipa"
        @focus="focus"
        @keydown.enter.native="handleEnter(0)"
        :disabled="disabled"
        :validate-event="true"
      ></el-input>
      <div>&bull;</div>
      <el-input
        @input="(e) => checkFormat(e, 'b')"
        placeholder="0-255"
        :maxlength="3"
        v-model="ip.b"
        size="small"
        @blur="blur"
        ref="ipb"
        @focus="focus"
        @keydown.enter.native="handleEnter(1)"
        :disabled="disabled"
        :validate-event="true"
      ></el-input>
      <div>&bull;</div>
      <el-input
        @input="(e) => checkFormat(e, 'c')"
        placeholder="0-255"
        :maxlength="3"
        v-model="ip.c"
        size="small"
        @blur="blur"
        ref="ipc"
        @focus="focus"
        @keydown.enter.native="handleEnter(2)"
        :disabled="disabled"
        :validate-event="true"
      ></el-input>
      <div>&bull;</div>
      <el-input
        @input="(e) => checkFormat(e, 'd')"
        placeholder="0-255"
        :maxlength="3"
        v-model="ip.d"
        style="margin-right: 0"
        size="small"
        @blur="blur"
        ref="ipd"
        @focus="focus"
        :disabled="disabled"
        :validate-event="true"
      ></el-input>
    </div>
  </div>
</template>


<script>
export default {
  data() {
    return {
      ip: {
        a: "",
        b: "",
        c: "",
        d: "",
      },
    };
  },
  props: {
    value: {
      type: String,
      default: "",
    },
    disabled: Boolean,
  },
  watch: {
    value(val) {
      if (val && val !== "" && this.isValidIPv4(val)) {
        this.setIpFromString(val);
      } else if (val === ""|| !val) {
        this.ip = { a: "", b: "", c: "", d: "" };
      }
    },
  },
  created() {
    if (this.isValidIPv4(this.value)) {
      this.setIpFromString(this.value);
    }
  },
  methods: {
    // 方法：将IPv4地址字符串转换为对象
    setIpFromString(ip) {
      const [a, b, c, d] = ip.split(".");
      this.ip = { a, b, c, d };
    },

    // 方法：检查IPv4地址的格式是否合法
    isValidIPv4(ip) {
      const ipv4Pattern = /^(\d{1,3}\.){3}\d{1,3}$/;
      if (ipv4Pattern.test(ip)) {
        const parts = ip.split(".");
        return parts.every((part) => {
          const num = parseInt(part, 10);
          return num >= 0 && num <= 255 && (part === "0" || part[0] !== "0" || part.length === 1);
        });
      }
      return false;
    },

    // 方法：处理每个输入框的回车事件，跳转焦点
    handleEnter(index) {
      const nextIndex = index + 1;
      if (nextIndex < 4) {
        this.$refs[`ip${String.fromCharCode(97 + nextIndex)}`].focus(); // 97 是 'a' 的 ASCII 值
      }
    },

    // 方法：获取过滤后的IPv4值
    getIpValue() {
      return `${this.ip.a}.${this.ip.b}.${this.ip.c}.${this.ip.d}`;
    },

    // 方法：焦点事件
    focus() {
      if (this.ip.a && this.ip.b && this.ip.c && this.ip.d) {
        this.$emit("focus", this.getIpValue());
      }
    },

    // 方法：失焦事件
    blur() {
      if (this.ip.a && this.ip.b && this.ip.c && this.ip.d) {
        this.$emit("blur", this.getIpValue());
      }
    },

    // 方法：检查并过滤输入格式
    checkFormat(item, value) {
      let val = item.toString().replace(/[^0-9]/g, ""); // 清除非数字字符
      val = parseInt(val, 10);
      if (isNaN(val)) {
        val = ""; // 如果是非法数字，清空
      } else {
        val = Math.max(0, Math.min(255, val)); // 确保值在 0 到 255 之间
      }
      this.ip[value] = val;

      let o = {
        a: "b",
        b: "c",
        c: "d",
      };
      // 如果当前输入框达到 3 位数字，自动跳转到下一个输入框
      if (val && val.toString().length === 3 && value !== "d") {
        this.$refs[`ip${o[value]}`].focus();
      }

      // 当输入框内容合法时，触发父组件的 input 事件
      if (this.isValidIPv4(this.getIpValue())) {
        this.$emit("input", this.getIpValue());
      }
    },
  },
};
</script>


<style lang="scss" scoped>
.ipBox {
  display: flex;
  align-items: flex-start;
}

.el-input {
  margin: 0 4px;
  width: 70px;
}

</style>

