vue實(shí)現(xiàn)一個(gè)6個(gè)輸入框的驗(yàn)證碼輸入組件功能的實(shí)例代碼
要實(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 lang="scss"> .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)中,分享給大家。
到此這篇關(guān)于vue實(shí)現(xiàn)一個(gè)6個(gè)輸入框的驗(yàn)證碼輸入組件的文章就介紹到這了,更多相關(guān)vue實(shí)現(xiàn)輸入框的驗(yàn)證碼輸入組件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue+ElementUI啟動(dòng)vue卡死的問(wèn)題及解決
這篇文章主要介紹了Vue+ElementUI啟動(dòng)vue卡死的問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03vue實(shí)現(xiàn)的請(qǐng)求服務(wù)器端API接口示例
這篇文章主要介紹了vue實(shí)現(xiàn)的請(qǐng)求服務(wù)器端API接口,結(jié)合實(shí)例形式分析了vue針對(duì)post、get、patch、put等請(qǐng)求的封裝與調(diào)用相關(guān)操作技巧,需要的朋友可以參考下2019-05-05Vue中使用方法、計(jì)算屬性或觀察者的方法實(shí)例詳解
這篇文章主要介紹了Vue中如何使用方法、計(jì)算屬性或觀察者的相關(guān)知識(shí),非常不錯(cuò),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下2018-10-10VUE中鼠標(biāo)滾輪使div左右滾動(dòng)的方法詳解
這篇文章主要給大家介紹了關(guān)于VUE中鼠標(biāo)滾輪使div左右滾動(dòng)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12Vue數(shù)據(jù)雙向綁定的實(shí)現(xiàn)方式講解
Vue數(shù)據(jù)雙向綁定原理:Vue內(nèi)部通過(guò)Object.defineProperty方法屬性攔截的方式,把data對(duì)象里每個(gè)數(shù)據(jù)的讀寫轉(zhuǎn)化成getter/setter,當(dāng)數(shù)據(jù)變化時(shí)通知視圖更新2022-08-08vue2.0+vue-dplayer實(shí)現(xiàn)hls播放的示例
這篇文章主要介紹了vue2.0+vue-dplayer實(shí)現(xiàn)hls播放的示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-03-03