最近的一个需求:输入邀请码并且每格限制输入一位数,共计六位数 类似于手机验证

上个月产品提的需求,要求输入邀请码为六位并且每个都是单独的输入框,且每个输入框只能输入一位不可重复。

大概是这样一个的一个样式:

 接下来我们来实现:

下面这段是样式

<template>
  <div class="ys-verification">
    <div class="input-wrapper" v-for="item in amount" :key="item">
      <input type="number" oninput="if(value.length>1)value=value.slice(0,1)" @paste="handlePaste" title="code" v-focus="(item - 1) === currentIndex" maxlength="1" @input="handleInput($event,(item-1))" @keyup.delete="onDelete($event,(item-1))"  v-model="code[item-1]">
    </div>
  </div>
</template>

<style lang="less" scoped>
  .ys-verification{
    width:100%;
    display: flex;
    justify-content: space-around;
    .input-wrapper{
      width: 15%;
      height: 0;
      padding-bottom:20%;
      position: relative;

      input{
        position: absolute;
        left: 0;
        width: 100%;
        height: 100%;
        text-align: center;
        transition: all 0.3s;
        font-size: 7vw;
        color: #333333;
        background-color: #d7d7d7;
      }
      input::-webkit-outer-spin-button,
      input::-webkit-inner-spin-button {
          -webkit-appearance: none;
      }
      input[type="number"]{
          -moz-appearance: textfield;
      }
    }
  }
</style>

这里是去除掉input属性为number的时候带来的上下箭头:

input[type="number"]{
    -moz-appearance: textfield;
}

接下来是JavaScript的逻辑部分:

<script>
export default {
  name: 'VerificationCodeInput',
  props: {
    amount: {
      type: Number,
      default: 6
    }
  },
  directives: {
    focus: {
      componentUpdated: function (el, obj) {
        obj.value && el.focus()
      }
    }
  },
  created () {
    this.code = new Array(this.amount).fill('')
  },
  methods: {
    handleInput (e, index) {
      this.currentIndex = index
      e.target.value = this.validateNumber(e.target.value)
      e.target.value !== '' && ++this.currentIndex
      if(this.code && this.code.length>=6){
        e.srcElement.blur();
      }
      !this.code.includes('') && this.$emit('onCompleted', this.code.join(''))
      
    },
    onDelete (e, index) {
      if (e.target.value === '') {
        this.currentIndex = index - 1
      }
    },
    validateNumber (val) {
      return val.replace(/\D/g, '')
    },
    handlePaste (e) {
      e.preventDefault()
    }
  },
  data () {
    return {
      code: [],
      currentIndex: 0
    }
  }
}
</script>

整体代码如下

<template>
  <div class="ys-verification">
    <div class="input-wrapper" v-for="item in amount" :key="item">
      <input type="number" oninput="if(value.length>1)value=value.slice(0,1)" @paste="handlePaste" title="code" v-focus="(item - 1) === currentIndex" maxlength="1" @input="handleInput($event,(item-1))" @keyup.delete="onDelete($event,(item-1))"  v-model="code[item-1]">
    </div>
  </div>
</template>

<script>
export default {
  name: 'VerificationCodeInput',
  props: {
    amount: {
      type: Number,
      default: 6
    }
  },
  directives: {
    focus: {
      componentUpdated: function (el, obj) {
        obj.value && el.focus()
      }
    }
  },
  created () {
    this.code = new Array(this.amount).fill('')
  },
  methods: {
    handleInput (e, index) {
      this.currentIndex = index
      e.target.value = this.validateNumber(e.target.value)
      e.target.value !== '' && ++this.currentIndex
      if(this.code && this.code.length>=6){
        e.srcElement.blur();
      }
      !this.code.includes('') && this.$emit('onCompleted', this.code.join(''))
      
    },
    onDelete (e, index) {
      if (e.target.value === '') {
        this.currentIndex = index - 1
      }
    },
    validateNumber (val) {
      return val.replace(/\D/g, '')
    },
    handlePaste (e) {
      e.preventDefault()
    }
  },
  data () {
    return {
      code: [],
      currentIndex: 0
    }
  }
}
</script>

<style lang="less" scoped>
  .ys-verification{
    width:100%;
    display: flex;
    justify-content: space-around;
    .input-wrapper{
      width: 15%;
      height: 0;
      padding-bottom:20%;
      position: relative;

      input{
        position: absolute;
        left: 0;
        width: 100%;
        height: 100%;
        text-align: center;
        transition: all 0.3s;
        font-size: 7vw;
        color: #333333;
        background-color: #d7d7d7;
      }
      input::-webkit-outer-spin-button,
      input::-webkit-inner-spin-button {
          -webkit-appearance: none;
      }
      input[type="number"]{
          -moz-appearance: textfield;
      }
    }
  }
</style>

这样我们就可以封装为组件来适用了

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值