vue完成输入金额框/验证码框/密码框可用的组件

image.png

呈现的效果大概是这样的,验证码框和密码框都是可以使用这套代码的,只是修改样式而已.
主要功能是可以实现输入数字以后(用正则限定了只可以输入数字),光标自动下跳,删除自动上跳.键入以后输入框原数据清空,未做更改,失焦之后输入框数据不变.
找了很久没找到合适的,最终还是自己完成了一个.代码注释也写的比较清晰.

代码如下(本人编程能力一般所以写的也比较简单通俗,如果真的被大佬看到,有什么不好的地方请马上指出谢谢):
html部分

<div class="verifyCode">
    <div class="verifyCodeItem" v-for="p in inputNums" :key="p">
      <input
        type="text"
        @input="inputFun($event,p)"
        @focus="onInputIn($event,p)"
        @blur="onInputOut($event,p)"
        @keyup.delete="onInputDelete($event,p)"
        :value="code[p-1]"
        :class="{success: code[p-1]===0}"
      />
      <span v-if="p==2">亿</span>
      <span v-if="p==6">万</span>
      <span v-if="p==10">.</span>
      <span v-if="p==12">份</span>
    </div>
  </div>

js部分

export default {
  props: {
    inputNums: {
      type: Number,
      default: 12
    },
    value: {
      type: String,
      default: '000000000000'
    },
    realValue: {
      type: String
    }
  },
  data () {
    return {
      code: this.value.split(''),
      historyVal: '',
      isChange: false
    }
  },
  methods: {
    // 获取焦点时
    onInputIn (e, p) {
      this.historyVal = this.code[p - 1]
      this.$set(this.code, p - 1, '')
    },
    // 失去焦点时
    onInputOut (e, p) {
      if (this.isChange) {
        this.isChange = false
        this.historyVal = this.code[p - 1]
      } else {
        this.$set(this.code, p - 1, this.historyVal)
      }
      // 失去焦点时传递当前code值
      let newVal = this.code.map(item => {
        if (item === '' || item === 'underfined') {
          item = '0'
        }
        return item
      })
      this.$emit('getVal', (newVal.join('') / 100).toString())
    },
    // 键入内容时
    inputFun (e, p) {
      let ele = e.target
      let siblingsNode = ele.parentNode.parentNode.children

      // 获取填入的值,并且存入
      let value = ele.value.replace(/[^\d]/g, '').slice(-1)
      ele.parentNode.value = value
      this.$set(this.code, p - 1, value)
      // 边界值处理
      if (p >= siblingsNode.length - 1) {
        p = siblingsNode.length - 1
      }
      // 记录更改,下一个元素获得焦点
      if (value) {
        this.isChange = true
        siblingsNode[p].children[0].focus()
      }
    },
    // 按下删除键(delete/backspace)时
    onInputDelete (e, p) {
      let ele = e.target
      let siblingsNode = ele.parentNode.parentNode.children
      // 当前光标所指的位置数值是0
      this.historyVal = 0
      this.code[p - 1] = 0
      // 边界值处理
      if (p <= 2) {
        p = 2
      }
      siblingsNode[p - 2].children[0].focus()
    }
  }
}

css部分

@mixin border() {
  border: 0.5px solid #dbd8d2;
  background-color: #ebe8e2;
  box-shadow: inset 0px 15px 10px -15px #c6c3be;
}
.verifyCode {
  display: flex;
  color: #38383b;
  .verifyCodeItem {
    display: flex;
    align-items: baseline;
    > span {
      margin: 0 5px;
    }
  }
  input {
    @include border();
    font-size: 14px;
    margin-left: 2px;
    width: 30px;
    height: 40px;
    border-radius: 5px;
    text-align: center;
    color: #a08d79;
    font-size: 20px;
    &:first {
      margin-left: 0;
    }
    &:focus {
      outline-color: #a08d79;
      outline-width: 0.5px;
    }
    &.success {
      border-color: #dbd8d2;
      border-width: 0.5px;
      transition: border-color 0.5s;
      outline: none;
    }
  }
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。