vue中使用element绘制一个Ip输入框组件

今天无聊写了一个可以控制不同大小的Ip输入框组件

使用

在这里插入图片描述

呈现

在这里插入图片描述

<template>
  <div>
    <div :class="dynamicSetIpBoxStyle">
      <el-input v-model.number="ip1"
                maxlength='3' ref='ip1'
                :class="dynamicSetIpInputStyle"
                onkeyup="value=value.replace(/[^\d]/g,'')"
                @keyup.native="keyupEvent(1,$event)"
                @blur="submitIp"
                @input="(val) => handleInpIp(val,'ip1')"
                :size="inputSize"></el-input>
      <span class="dot">.</span>
      <el-input v-model.number="ip2"
                maxlength='3' ref='ip2'
                :class="dynamicSetIpInputStyle"
                onkeyup="value=value.replace(/[^\d]/g,'')"
                @keyup.native="keyupEvent(2,$event)"
                @blur="submitIp"
                @input="(val) => handleInpIp(val,'ip2')"
                :size="inputSize"></el-input>
      <span class="dot">.</span>
      <el-input v-model.number="ip3"
                maxlength='3' ref='ip3'
                :class="dynamicSetIpInputStyle"
                onkeyup="value=value.replace(/[^\d]/g,'')"
                @keyup.native="keyupEvent(3,$event)"
                @blur="submitIp"
                @input="(val) => handleInpIp(val,'ip3')"
                :size="inputSize"></el-input>
      <span class="dot">.</span>
      <el-input v-model.number="ip4"
                maxlength='3' ref='ip4'
                :class="dynamicSetIpInputStyle"
                onkeyup="value=value.replace(/[^\d]/g,'')"
                @keyup.native="keyupEvent(4,$event)"
                @blur="submitIp"
                @input="(val) => handleInpIp(val,'ip4')"
                :size="inputSize"></el-input>
      <i class="el-icon-circle-close" :class="dynamicSetCircleCloseStyle" @click="clearValue"></i>
    </div>
  </div>
</template>

<script>
export default {
  name: "IpModel",
  model:{
    prop:"value",
    event:"change",
  },
  props:{
    //inputSize  根element是size一样  有三种选择  mini small medium
    inputSize:{
      type:String,
      default:""
    },
    //boxWidth 三种选择  miniWidth  smallWidth  mediumWidth  不满足样式请自定义样   如下style
    boxWidth:String,
    value:String,
    echoIp:String
  },
  data() {
    return {
      ip1: null,
      ip2: null,
      ip3: null,
      ip4: null,
      //默认样式
      dynamicSetIpBoxStyle:'ipBoxSmall',
      dynamicSetIpInputStyle:'ipinputSmall',
      dynamicSetCircleCloseStyle:'closeSmall'
    };
  },
  created() {
    if(this.boxWidth === 'miniWidth'){
      this.dynamicSetIpBoxStyle = 'ipBoxMini';
      this.dynamicSetIpInputStyle = 'ipinputMini';
      this.dynamicSetCircleCloseStyle = 'closeMini';
    }
    if(this.boxWidth === 'mediumWidth'){
      this.dynamicSetIpBoxStyle = 'ipBoxMedium';
      this.dynamicSetIpInputStyle = 'ipinputMedium';
      this.dynamicSetCircleCloseStyle = 'closeMedium';
    }
    //自定义样式在这里配置
    if(this.boxWidth === 'scanWidth'){
      this.dynamicSetIpBoxStyle = 'ipBoxScan';
      this.dynamicSetIpInputStyle = 'ipinputScan';
      this.dynamicSetCircleCloseStyle = 'closeScan';
    }
  },
  watch:{
    echoIp:{
      handler(val){
        if(val){
          let ipList = val.split('.');
          this.ip1 = ipList[0];
          this.ip2 = ipList[1];
          this.ip3 = ipList[2];
          this.ip4 = ipList[3];
          this.$emit("change",val)
        }
      }
    },
    value:{
      handler(val){
        if(val !== null && val !== undefined){
          let ipList = val.split('.');
          this.ip1 = ipList[0];
          this.ip2 = ipList[1];
          this.ip3 = ipList[2];
          this.ip4 = ipList[3];
        }else {
          this.ip1 = null;
          this.ip2 = null;
          this.ip3 = null;
          this.ip4 = null;
        }
        if(this.ip1 != null && this.ip2 != null && this.ip3 != null && this.ip4 != null) {
          let echo =  this.ip1+'.'+this.ip2+'.'+this.ip3+'.'+this.ip4
          this.$emit("change",echo)
        }
      },
    },

  },
  computed: {
    isRightVal () {
      //判断填入的四个ip值是否为数字,只有有一个为非数字则为true
      let reg = /[^\d]/g;
      return reg.test(this.ip1) || reg.test(this.ip2) || reg.test(this.ip3) || reg.test(this.ip4);
    }
  },
  methods: {
    //监听键盘
    keyupEvent (index,e) {
      //按下.键跳到下一个输入框(同理可做出其他按键的跳转输入框)
      if (e.keyCode === 110 || e.keyCode === 190) {//不同键盘键位对应 . 的值 87键->190  104键->110
        //这里尝试过用this.focusInput发现没有效果(具体原因暂未知....),待你们完善
        if (index == 1) {
          this.$nextTick(() => {
            this.$refs.ip2.focus();
          });
        } else if (index == 2) {
          this.$nextTick(() => {
            this.$refs.ip3.focus();
          });
        } else {
          this.$nextTick(() => {
            this.$refs.ip4.focus();
          });
        }
      }
    },
    //到失去输入框焦点时
    submitIp () {
      //失去焦点判断值是否输入完整,并向父组件传整个ip值
      if(this.ip1 !=null && this.ip2 != null && this.ip3 != null && this.ip4 != null) {
        if (this.isRightVal) {
          //这里也可以加个提示框之类的提示用户
          this.clearValue();
        }else {
          let ipVal = this.ip1 + '.' + this.ip2 + '.' + this.ip3 + '.' + this.ip4;
          if (this.ip4 == 0 || this.ip4 == 255 || this.ip1 == 0 || this.ip1 == 255) {
            this.$message.error(ipVal + "-为保留ip")
            return;
          }
          this.$emit('change', ipVal);
          this.$parent.$emit("el.form.change"); //这是防止elementui的form表单验证必填项时显示文字的也就是required,用不到可不写
        }
      }else {
        return;
      }
    },
    //输入的值
    handleInpIp(val, key) {
      //输入数据时  就显示图标
      //当一个表单   多次使用该组件   会使getElementsByClassName获取多个class   暂时不知道怎么去判断    你们可以去完善
     // document.getElementsByClassName(this.dynamicSetCircleCloseStyle).item(0).style.display = 'inline-block';
      //判断输入的ip值  0和255位保留ip  不使用
      if(parseInt(val) > 254) {
        //这里使用 this.focusInput()  发现没有效果,不能跳到下一个输入框(具体原因暂未知....)   留给你们去研究  研究清楚了  记得补充..............
        //补充:
        //输入值超过255,则显示为254,并且跳到下一个输入框
        switch(key) {
          case "ip1":
            this.ip1 = 254;
            this.$refs.ip2.focus();
            break;
          case "ip2":
            this.ip2 = 254;
            this.$refs.ip3.focus();
            break;
          case "ip3":
            this.ip3 = 254;
            this.$refs.ip4.focus();
            break;
          case "ip4":
            this.ip4 = 254;
            break;
          default:
            break;
        }
      }else if(parseInt(val) <= 254 && parseInt(val) >= 100){
        //输入三位数自动跳到下一个输入值
        switch(key) {
          case "ip1":
            this.$refs.ip2.focus();
            break;
          case "ip2":
            this.$refs.ip3.focus();
            break;
          case "ip3":
            this.$refs.ip4.focus();
            break;
          default:
            break;
        }
      }
    },

    clearValue () {
      //重置ip输入框
      this.ip1 = null;
      this.ip2 = null;
      this.ip3 = null;
      this.ip4 = null;
      this.$emit('getIpVal',''); //清除输入框传空值
      //清空输入框时,隐藏图标  当多次使用该组件时    会有多个class不能指定对应点击的class,未达到效果,待你们完善
      // document.getElementsByClassName(this.dynamicSetCircleCloseStyle).item(0).style.display = 'none';
    },
  },


}
</script>

<style scoped lang='less'>
.dot {
  display: inline-block;
  width: 4px;
  height: 100%;
  line-height: 50%;
}
/***********   medium样式 为默认样式   **********/
.ipBoxMedium{
  border: 1px solid #ccc;
  display: inline-block;
  border-radius: 5px;
  line-height: 0px;
  position: relative;
  top: 0;
  left: 0;
}
.ipinputMedium{
  display: inline-block;
  width: 65px;
  /deep/ .el-input__inner {
    border: 0;
  }
  font-size: 16px;
}
.closeMedium{
  display: none;
  font-size: 12px;
  cursor: pointer;
  position: absolute;
  right:0px;
  top: 12px;
}
&:hover {
  .closeMedium{
    display: inline-block;
  }
}
/***********   small样式    **********/
.ipBoxSmall{
  border: 1px solid #ccc;
  display: inline-block;
  border-radius: 5px;
  line-height: 0px;
  width: 216px;
  position: relative;
  top: 0;
  left: 0;
}
.ipinputSmall{
  display: inline-block;
  width: 50px;
  /deep/ .el-input__inner {
    padding: 0 10px;
    text-align: center;
    border: 0;
  }
  font-size: 14px;
}
.closeSmall{
  display: none;
  font-size: 12px;
  cursor: pointer;
  position: absolute;
  right:0px;
  top: 13px;
}
&:hover {
  .closeSmall{
    display: inline-block;
  }
}
/***********   mini样式    **********/
.ipBoxMini{
  border: 1px solid #ccc;
  display: inline-block;
  border-radius: 5px;
  line-height: 0px;
  width: 192px;
  position: relative;
  top: 0;
  left: 0;
}
.ipinputMini{
  display: inline-block;
  width: 44px;
  /deep/ .el-input__inner {
    padding:2px;
    text-align: center;
    border: 0;
  }
  font-size: 14px;

}
.closeMini{
  display: none;
  font-size: 12px;
  cursor: pointer;
  position: absolute;
  right:0px;
  top: 12px;
}
&:hover {
  .closeMini{
    display: inline-block;
  }
}
/***********   IP扫描样式    **********/
.ipBoxScan{
  border: 1px solid #ccc;
  display: inline-block;
  border-radius: 6px;
  line-height: 0px;
  width: 190px;
  position: relative;
  top: 0;
  left: 0;
}
.ipinputScan{
  display: inline-block;
  width: 44px;
  /deep/ .el-input__inner {
    padding:2px;
    //text-align: center;
    border: 0;
  }
  font-size: 14px;

}
.closeScan{
  display: none;
  font-size: 8px;
  cursor: pointer;
  position: absolute;
  right:0px;
  top: 8px;
}
//页面显示时就显示
&:hover {
  .closeScan{
    display: inline-block;
  }
}
</style>

通过动态控制class,使用样式,已达到不同效果!
需要完善的就在后面留言吧!!!
————————————————————————————————————————————————————————
完善

<template>
  <div>
    <div :class="dynamicSetIpBoxStyle">
      <el-input v-model.number="ip1"
                maxlength='3' ref='ip1'
                :class="dynamicSetIpInputStyle"
                onkeyup="value=value.replace(/[^\d]/g,'')"
                @keyup.native="keyupEvent(1,$event)"
                @blur="submitIp"
                @input="(val) => handleInpIp(val,'ip1',circleId)"
                :size="inputSize"></el-input>
      <span class="dot">.</span>
      <el-input v-model.number="ip2"
                maxlength='3' ref='ip2'
                :class="dynamicSetIpInputStyle"
                onkeyup="value=value.replace(/[^\d]/g,'')"
                @keyup.native="keyupEvent(2,$event)"
                @blur="submitIp"
                @input="(val) => handleInpIp(val,'ip2',circleId)"
                :size="inputSize"></el-input>
      <span class="dot">.</span>
      <el-input v-model.number="ip3"
                maxlength='3' ref='ip3'
                :class="dynamicSetIpInputStyle"
                onkeyup="value=value.replace(/[^\d]/g,'')"
                @keyup.native="keyupEvent(3,$event)"
                @blur="submitIp"
                @input="(val) => handleInpIp(val,'ip3',circleId)"
                :size="inputSize"></el-input>
      <span class="dot">.</span>
      <el-input v-model.number="ip4"
                maxlength='3' ref='ip4'
                :class="dynamicSetIpInputStyle"
                onkeyup="value=value.replace(/[^\d]/g,'')"
                @keyup.native="keyupEvent(4,$event)"
                @blur="submitIp"
                @input="(val) => handleInpIp(val,'ip4',circleId)"
                :size="inputSize"></el-input>
      <i class="el-icon-circle-close" :class="dynamicSetCircleCloseStyle" :id="circleId" @click="clearValue(circleId)"></i>
    </div>
  </div>
</template>

<script>
//引入nanoid 解决生产不同的id
import {nanoid} from 'nanoid'
export default {
  name: "IpModel",
  model:{
    prop:"value",
    event:"change",
  },
  props:{
    //inputSize  根element是size一样  有三种选择  mini small medium
    inputSize:{
      type:String,
      default:""
    },
    //boxWidth 三种选择  miniWidth  smallWidth  mediumWidth  不满足样式请自定义样   如下style
    boxWidth:String,
    value:String,
    echoIp:String
  },
  data() {
    return {
      ip1: null,
      ip2: null,
      ip3: null,
      ip4: null,
      circleId:'',
      //默认样式
      dynamicSetIpBoxStyle:'ipBoxSmall',
      dynamicSetIpInputStyle:'ipinputSmall',
      dynamicSetCircleCloseStyle:'closeSmall'
    };
  },
  created() {
    this.circleId = nanoid();
    if(this.boxWidth === 'miniWidth'){
      this.dynamicSetIpBoxStyle = 'ipBoxMini';
      this.dynamicSetIpInputStyle = 'ipinputMini';
      this.dynamicSetCircleCloseStyle = 'closeMini';
    }
    if(this.boxWidth === 'mediumWidth'){
      this.dynamicSetIpBoxStyle = 'ipBoxMedium';
      this.dynamicSetIpInputStyle = 'ipinputMedium';
      this.dynamicSetCircleCloseStyle = 'closeMedium';
    }
    //自定义样式在这里配置
    if(this.boxWidth === 'scanWidth'){
      this.dynamicSetIpBoxStyle = 'ipBoxScan';
      this.dynamicSetIpInputStyle = 'ipinputScan';
      this.dynamicSetCircleCloseStyle = 'closeScan';
    }
  },
  watch:{
    echoIp:{
      handler(val){
        if(val){
          //当有值时,显示
          document.getElementById(this.circleId).style.display = 'inline-block';
          let ipList = val.split('.');
          this.ip1 = ipList[0];
          this.ip2 = ipList[1];
          this.ip3 = ipList[2];
          this.ip4 = ipList[3];
          this.$emit("change",val)
        }
      }
    },
    value:{
      handler(val){
        if(val !== null && val !== undefined){
          let ipList = val.split('.');
          this.ip1 = ipList[0];
          this.ip2 = ipList[1];
          this.ip3 = ipList[2];
          this.ip4 = ipList[3];
        }else {
          this.ip1 = null;
          this.ip2 = null;
          this.ip3 = null;
          this.ip4 = null;
        }
        if(this.ip1 != null && this.ip2 != null && this.ip3 != null && this.ip4 != null) {
          let echo =  this.ip1+'.'+this.ip2+'.'+this.ip3+'.'+this.ip4
          this.$emit("change",echo)
        }
      },
    },

  },
  computed: {
    isRightVal () {
      //判断填入的四个ip值是否为数字,只有有一个为非数字则为true
      let reg = /[^\d]/g;
      return reg.test(this.ip1) || reg.test(this.ip2) || reg.test(this.ip3) || reg.test(this.ip4);
    }
  },
  methods: {
    //监听键盘
    keyupEvent (index,e) {
      //按下.键跳到下一个输入框(同理可做出其他按键的跳转输入框)
      if (e.keyCode === 110 || e.keyCode === 190) {//不同键盘键位对应 . 的值 87键->190  104键->110
        //这里尝试过用this.focusInput发现没有效果(具体原因暂未知....),待你们完善
        if (index == 1) {
          this.$nextTick(() => {
            this.$refs.ip2.focus();
          });
        } else if (index == 2) {
          this.$nextTick(() => {
            this.$refs.ip3.focus();
          });
        } else {
          this.$nextTick(() => {
            this.$refs.ip4.focus();
          });
        }
      }
    },
    //到失去输入框焦点时
    submitIp () {
      //失去焦点判断值是否输入完整,并向父组件传整个ip值
      if(this.ip1 !=null && this.ip2 != null && this.ip3 != null && this.ip4 != null) {
        if (this.isRightVal) {
          //这里也可以加个提示框之类的提示用户
          this.clearValue();
        }else {
          let ipVal = this.ip1 + '.' + this.ip2 + '.' + this.ip3 + '.' + this.ip4;
          if (this.ip4 == 0 || this.ip4 == 255 || this.ip1 == 0 || this.ip1 == 255) {
            this.$message.error(ipVal + "-为保留ip")
            return;
          }
          this.$emit('change', ipVal);
          this.$parent.$emit("el.form.change"); //这是防止elementui的form表单验证必填项时显示文字的也就是required,用不到可不写
        }
      }else {
        return;
      }
    },
    //输入的值
    handleInpIp(val, key,cid) {
      //输入数据时  就显示图标
      //当一个表单   多次使用该组件   会使getElementsByClassName获取多个class   暂时不知道怎么去判断    你们可以去完善
      //已解決  使用id
       document.getElementById(cid).style.display = 'inline-block';
      //判断输入的ip值  0和255位保留ip  不使用
      if(parseInt(val) > 254) {
        //这里使用 this.focusInput()  发现没有效果,不能跳到下一个输入框(具体原因暂未知....)   留给你们去研究  研究清楚了  记得补充..............
        //补充:
        //输入值超过255,则显示为254,并且跳到下一个输入框
        switch(key) {
          case "ip1":
            this.ip1 = 254;
            this.$refs.ip2.focus();
            break;
          case "ip2":
            this.ip2 = 254;
            this.$refs.ip3.focus();
            break;
          case "ip3":
            this.ip3 = 254;
            this.$refs.ip4.focus();
            break;
          case "ip4":
            this.ip4 = 254;
            break;
          default:
            break;
        }
      }else if(parseInt(val) <= 254 && parseInt(val) >= 100){
        //输入三位数自动跳到下一个输入值
        switch(key) {
          case "ip1":
            this.$refs.ip2.focus();
            break;
          case "ip2":
            this.$refs.ip3.focus();
            break;
          case "ip3":
            this.$refs.ip4.focus();
            break;
          default:
            break;
        }
      }
    },

    clearValue (cid) {
      //重置ip输入框
      this.ip1 = null;
      this.ip2 = null;
      this.ip3 = null;
      this.ip4 = null;
      this.$emit('getIpVal',''); //清除输入框传空值
      //清空输入框时,隐藏图标  当多次使用该组件时    会有多个class不能指定对应点击的class,未达到效果,待你们完善
      //已解決
      document.getElementById(cid).style.display = 'none';
    },
  },


}
</script>

<style scoped lang='less'>
.dot {
  display: inline-block;
  width: 4px;
  height: 100%;
  line-height: 50%;
}
/***********   medium样式 为默认样式   **********/
.ipBoxMedium{
  border: 1px solid #ccc;
  display: inline-block;
  border-radius: 5px;
  line-height: 0px;
  position: relative;
  top: 0;
  left: 0;
}
.ipinputMedium{
  display: inline-block;
  width: 65px;
  /deep/ .el-input__inner {
    border: 0;
  }
  font-size: 16px;
}
.closeMedium{
  display: none;
  font-size: 12px;
  cursor: pointer;
  position: absolute;
  right:0px;
  top: 12px;
}
//&:hover {
//  .closeMedium{
//    display: inline-block;
//  }
//}
/***********   small样式    **********/
.ipBoxSmall{
  border: 1px solid #ccc;
  display: inline-block;
  border-radius: 5px;
  line-height: 0px;
  width: 216px;
  position: relative;
  top: 0;
  left: 0;
}
.ipinputSmall{
  display: inline-block;
  width: 48px;
  /deep/ .el-input__inner {
    padding: 0 10px;
    text-align: center;
    border: 0;
  }
  font-size: 14px;
}
.closeSmall{
  display: none;
  font-size: 12px;
  cursor: pointer;
  position: absolute;
  right:0px;
  top: 13px;
}
//&:hover {
//  .closeSmall{
//    display: inline-block;
//  }
//}
/***********   mini样式    **********/
.ipBoxMini{
  border: 1px solid #ccc;
  display: inline-block;
  border-radius: 5px;
  line-height: 0px;
  width: 192px;
  position: relative;
  top: 0;
  left: 0;
}
.ipinputMini{
  display: inline-block;
  width: 44px;
  /deep/ .el-input__inner {
    padding:2px;
    text-align: center;
    border: 0;
  }
  font-size: 14px;

}
.closeMini{
  display: none;
  font-size: 12px;
  cursor: pointer;
  position: absolute;
  right:0px;
  top: 12px;
}
//&:hover {
//  .closeMini{
//    display: inline-block;
//  }
//}
/***********   IP扫描样式    **********/
.ipBoxScan{
  border: 1px solid #ccc;
  display: inline-block;
  border-radius: 6px;
  line-height: 0px;
  width: 190px;
  position: relative;
  top: 0;
  left: 0;
}
.ipinputScan{
  display: inline-block;
  width: 44px;
  /deep/ .el-input__inner {
    padding:2px;
    //text-align: center;
    border: 0;
  }
  font-size: 14px;

}
.closeScan{
  display: none;
  font-size: 8px;
  cursor: pointer;
  position: absolute;
  right:0px;
  top: 8px;
}
//页面显示时就显示
//&:hover {
//  .closeScan{
//    display: inline-block;
//  }
//}

</style>
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值