<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          在 Vue 中簡(jiǎn)單實(shí)現(xiàn)一個(gè) 6 個(gè)輸入框的驗(yàn)證碼組件

          共 5816字,需瀏覽 12分鐘

           ·

          2021-07-27 21:28

          來(lái)源 | https://segmentfault.com/a/1190000023041401

          要實(shí)現(xiàn)的功能:
          完全和單輸入框一樣的操作,甚至可以插入覆蓋:
          1,限制輸入數(shù)字
          2,正常輸入
          3,backspace刪除
          4,paste任意位置粘貼輸入
          5,光標(biāo)選中一個(gè)數(shù)字,滾輪可以微調(diào)數(shù)字大小,限制0-9
          6,123|456 自動(dòng)覆蓋光標(biāo)后輸入的字符,此時(shí)光標(biāo)在3后,繼續(xù)輸入111,會(huì)得到123111,而不用手動(dòng)刪除456
          7,封裝成vue單文件組件,方便任意調(diào)用。
          最終效果如圖:

          模板代碼

          <template>  <div class="input-box">    <div class="input-content" @keydown="keydown" @keyup="keyup" @paste="paste" @mousewheel="mousewheel"        @input="inputEvent">      <input max="9" min="0" maxlength="1" data-index="0" v-model.trim.number="input[0]" type="number"          ref="firstinput"/>      <input max="9" min="0" maxlength="1" data-index="1" v-model.trim.number="input[1]" type="number"/>      <input max="9" min="0" maxlength="1" data-index="2" v-model.trim.number="input[2]" type="number"/>      <input      <input max="9" min="0" maxlength="1" data-index="4" v-model.trim.number="input[4]" type="number"/>      <input max="9" min="0" maxlength="1" data-index="5" v-model.trim.number="input[5]" type="number"/>    </div>  </div></template>

          實(shí)現(xiàn)了鍵盤的keydown/keyup/paste/input和鼠標(biāo)滾輪mousewheel事件
          使用了6個(gè)輸入框的方案來(lái)實(shí)現(xiàn)。

          樣式部分:使用了scss模式

          <style scoped>  .input-box {    .input-content {      width: 512px;      height: 60px;      display: flex;      align-items: center;      justify-content: space-between;
          input { color: inherit; font-family: inherit; border: 0; outline: 0; border-bottom: 1px solid #919191; height: 60px; width: 60px; font-size: 44px; text-align: center; } }
          input::-webkit-outer-spin-button, input::-webkit-inner-spin-button { appearance: none; margin: 0; } }</style>

          具體實(shí)現(xiàn)邏輯:主要實(shí)現(xiàn)以上幾個(gè)鍵盤事件操作。

          <script>  export default {    data() {      return {        // 存放粘貼進(jìn)來(lái)的數(shù)字        pasteResult: [],      };    },    props: ['code'],    computed: {      input() {        // code 是父組件傳進(jìn)來(lái)的默認(rèn)值,必須是6位長(zhǎng)度的數(shù)組,這里就不再做容錯(cuò)判斷處理        // 最后空數(shù)組是默認(rèn)值        return this.code || this.pasteResult.length === 6 ? this.pasteResult : ['', '', '', '', '', '']      }    },    methods: {      // 解決一個(gè)輸入框輸入多個(gè)字符      inputEvent(e) {        var index = e.target.dataset.index * 1;        var el = e.target;        this.$set(this.input, index, el.value.slice(0, 1))      },      keydown(e) {        var index = e.target.dataset.index * 1;        var el = e.target;        if (e.key === 'Backspace') {          if (this.input[index].length > 0) {            this.$set(this.input, index, '')          } else {            if (el.previousElementSibling) {              el.previousElementSibling.focus()              this.$set(this.input, index - 1, '')            }          }        } else if (e.key === 'Delete') {          if (this.input[index].length > 0) {            this.$set(this.input, index, '')          } else {            if (el.nextElementSibling) {              this.$set(this.input, index = 1, '')            }          }          if (el.nextElementSibling) {            el.nextElementSibling.focus()          }        } else if (e.key === 'Home') {          el.parentElement.children[0] && el.parentElement.children[0].focus()        } else if (e.key === 'End') {          el.parentElement.children[this.input.length - 1] && el.parentElement.children[this.input.length - 1].focus()        } else if (e.key === 'ArrowLeft') {          if (el.previousElementSibling) {            el.previousElementSibling.focus()          }        } else if (e.key === 'ArrowRight') {          if (el.nextElementSibling) {            el.nextElementSibling.focus()          }        } else if (e.key === 'ArrowUp') {          if (this.input[index] * 1 < 9) {            this.$set(this.input, index, (this.input[index] * 1 + 1).toString());          }        } else if (e.key === 'ArrowDown') {          if (this.input[index] * 1 > 0) {            this.$set(this.input, index, (this.input[index] * 1 - 1).toString());          }        }      },      keyup(e) {        var index = e.target.dataset.index * 1;        var el = e.target;        if (/Digit|Numpad/i.test(e.code)) {          this.$set(this.input, index, e.code.replace(/Digit|Numpad/i, ''));          el.nextElementSibling && el.nextElementSibling.focus();          if (index === 5) {            if (this.input.join('').length === 6) {              document.activeElement.blur();              this.$emit('complete', this.input);            }          }        } else {          if (this.input[index] === '') {            this.$set(this.input, index, '');          }        }      },      mousewheel(e) {        var index = e.target.dataset.index;        if (e.wheelDelta > 0) {          if (this.input[index] * 1 < 9) {            this.$set(this.input, index, (this.input[index] * 1 + 1).toString());          }        } else if (e.wheelDelta < 0) {          if (this.input[index] * 1 > 0) {            this.$set(this.input, index, (this.input[index] * 1 - 1).toString());          }        } else if (e.key === 'Enter') {          if (this.input.join('').length === 6) {            document.activeElement.blur();            this.$emit('complete', this.input);          }        }      },      paste(e) {        // 當(dāng)進(jìn)行粘貼時(shí)        e.clipboardData.items[0].getAsString(str => {          if (str.toString().length === 6) {            this.pasteResult = str.split('');            document.activeElement.blur();            this.$emit('complete', this.input);          }        })      }    },    mounted() {      // 等待dom渲染完成,在執(zhí)行focus,否則無(wú)法獲取到焦點(diǎn)      this.$nextTick(() => {        this.$refs.firstinput.focus()      })    },  }</script>

          如果你發(fā)現(xiàn)了bug,或者有優(yōu)化空間,歡迎你的指正和建議。我會(huì)隨時(shí)更新到原代碼當(dāng)中,分享給大家。

          本文完~


          瀏覽 152
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  蜜桃视频色五月婷婷 | 2020人人操 | 成人电影久久 | 俺来也俺也去成人女优 | 亚洲污污|