完全和单输入框一样的操作,甚至可以插入覆盖:
1,限制输入数字
2,正常输入
3,backspace删除
4,paste任意位置粘贴输入
5,光标选中一个数字,滚轮可以微调数字大小,限制0-9
6,123|456 自动覆盖光标后输入的字符,此时光标在3后,继续输入111,会得到123111,而不用手 动删除456
7,封装成vue单文件组件,方便任意调用。
效果:
页面模板代码
<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" vmodel.trim.number="input[0]" type="number" ref="firstinput"/> <input max="9" min="0" maxlength="1" data-index="1" vmodel.trim.number="input[1]" type="number"/> <input max="9" min="0" maxlength="1" data-index="2" vmodel.trim.number="input[2]" type="number"/> <input max="9" min="0" maxlength="1" data-index="4" vmodel.trim.number="input[4]" type="number"/> <input max="9" min="0" maxlength="1" data-index="5" vmodel.trim.number="input[5]" type="number"/> </div> </div> </template>
JS 逻辑代码
1 <script> 2 export default { 3 data() { 4 return { 5 pasteResult: [], 6 code: '' 7 } 8 }, 9 // props: ['code'], 10 computed: { 11 input() { 12 if (this.code && Array.isArray(this.code) && this.code.length === 6) { 13 return this.code 14 } else if (/^\d{6}$/.test(this.code.toString())) { 15 return this.code.toString().split('') 16 } else if (this.pasteResult.length === 6) { 17 return this.pasteResult 18 } else { 19 return new Array(6) 20 } 21 }, 22 }, 23 methods: { 24 // 解决一个输入框输入多个字符 25 inputEvent(e) { 26 var index = e.target.dataset.index * 1 27 var el = e.target 28 el.value = el.value 29 .replace(/Digit|Numpad/i, '') 30 // .replace(/1/g, '') 31 .slice(0, 1) 32 this.$set(this.input, index, el.value) 33 }, 34 keydown(e) { 35 var index = e.target.dataset.index * 1 36 var el = e.target 37 if (e.key === 'Backspace') { 38 if (this.input[index].length > 0) { 39 this.$set(this.input, index, '') 40 } else { 41 if (el.previousElementSibling) { 42 el.previousElementSibling.focus() 43 this.$set(this.input, index - 1, '') 44 } 45 } 46 } else if (e.key === 'Delete') { 47 if (this.input[index].length > 0) { 48 this.$set(this.input, index, '') 49 } else { 50 if (el.nextElementSibling) { 51 this.$set(this.input, (index = 1), '') 52 } 53 } 54 if (el.nextElementSibling) { 55 el.nextElementSibling.focus() 56 } 57 } else if (e.key === 'Home') { 58 el.parentElement.children[0] && el.parentElement.children[0].focus() 59 } else if (e.key === 'End') { 60 el.parentElement.children[this.input.length - 1] && 61 el.parentElement.children[this.input.length - 1].focus() 62 } else if (e.key === 'ArrowLeft') { 63 if (el.previousElementSibling) { 64 el.previousElementSibling.focus() 65 } 66 } else if (e.key === 'ArrowRight') { 67 if (el.nextElementSibling) { 68 el.nextElementSibling.focus() 69 } 70 } else if (e.key === 'ArrowUp') { 71 if (this.input[index] * 1 < 9) { 72 this.$set(this.input, index, (this.input[index] * 1 + 1).toString()) 73 } 74 } else if (e.key === 'ArrowDown') { 75 if (this.input[index] * 1 > 0) { 76 this.$set(this.input, index, (this.input[index] * 1 - 1).toString()) 77 } 78 } 79 }, 80 keyup(e) { 81 var index = e.target.dataset.index * 1 82 var el = e.target 83 // 解决输入e的问题 84 el.value = el.value 85 .replace(/Digit|Numpad/i, '') 86 // .replace(/1/g, '') 87 .slice(0, 1) 88 if (/Digit|Numpad/i.test(e.code)) { 89 // 必须在这里符直,否则输入框会是空值 90 this.$set(this.input, index, e.code.replace(/Digit|Numpad/i, '')) 91 el.nextElementSibling && el.nextElementSibling.focus() 92 if (index === 5) { 93 if (this.input.join('').length === 6) { 94 document.activeElement.blur() 95 this.$emit('complete', this.input) 96 } 97 } 98 } else { 99 if (this.input[index] === '') { 100 this.$set(this.input, index, '') 101 } 102 } 103 }, 104 mousewheel(e) { 105 var index = e.target.dataset.index 106 if (e.wheelDelta > 0) { 107 if (this.input[index] * 1 < 9) { 108 this.$set(this.input, index, (this.input[index] * 1 + 1).toString()) 109 } 110 } else if (e.wheelDelta < 0) { 111 if (this.input[index] * 1 > 0) { 112 this.$set(this.input, index, (this.input[index] * 1 - 1).toString()) 113 } 114 } else if (e.key === 'Enter') { 115 if (this.input.join('').length === 6) { 116 document.activeElement.blur() 117 this.$emit('complete', this.input) 118 } 119 } 120 }, 121 paste(e) { 122 // 当进行粘贴时 123 e.clipboardData.items[0].getAsString((str) => { 124 if (str.toString().length === 6) { 125 this.pasteResult = str.split('') 126 document.activeElement.blur() 127 this.$emit('complete', this.input) 128 this.pasteResult = [] 129 } else { 130 // 如果粘贴内容不合规,清除所有内容 131 this.input[0] = new Array(6) 132 } 133 }) 134 }, 135 }, 136 mounted() { 137 // 等待dom渲染完成,在执行focus,否则无法获取到焦点 138 this.$nextTick(() => { 139 this.$refs.firstinput.focus() 140 }) 141 }, 142 } 143 </script>
CSS 样式代码
<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; } input::-webkit-outer-spin-button, input::-webkit-inner-spin-button { appearance: none; margin: 0; } } </style>