Vue - 实现验证码输入组件
效果图功能分解输入效果自动换焦如何删除接收paste事件数据先行确定验证码位数 amout储存验证码的数组 code当前输入项的索引 currentIndex布局<template><div class="ys-verification"><div class="input-wrapper"
·
效果图
功能分解
- 输入效果
- 自动换焦
- 如何删除
- 接收paste事件
数据先行
- 确定验证码位数
amout
- 储存验证码的数组
code
- 当前输入项的索引
currentIndex
布局
<template>
<div class="ys-verification">
<div class="input-wrapper" v-for="item in amount" :key="item">
<input type="number" @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>
初始化code
created () {
this.code = new Array(this.amount).fill('')
},
如何实现自动换焦
A: 采用自定义指令实现
正如模板代码中展示的那样,为每一个input绑定了一个v-focus指令
directives: {
focus: {
componentUpdated: function (el, obj) {
obj.value && el.focus()
}
}
},
我们传入一个boolean值控制当前项是否获得焦点。
而Boolean值是由 (item - 1) === currentIndex
决定,因此我们只需要修改currentIndex
的值便可以实现自动换焦.
在哪里修改currentIndex
可以给Input绑定一个input事件,输入一位数字之后就让currentIndex + 1
methods: {
handleInput (e, index) {
this.currentIndex = index
e.target.value = this.validateNumber(e.target.value)
e.target.value !== '' && ++this.currentIndex
!this.code.includes('') && this.$emit('onCompleted', this.code.join(''))
},
validateNumber (val) {
return val.replace(/\D/g, '')
},
怎么删除
我们监听键盘事件,使用vue
的别名。删除之后退格。
@keyup.delete="onDelete($event,(item-1))"
//...
onDelete (e, index) {
if (e.target.value === '') {
this.currentIndex = index - 1
}
},
粘贴
后来有了新需求,要求能够粘贴。
but,
我不能获取到Item的值,就很难受。
所以就没搞定,就简直粘贴了。
然而,有的手机还是能够粘贴
handlePaste (e) {
e.preventDefault()
}
源码
<template>
<div class="ys-verification">
<div class="input-wrapper" v-for="item in amount" :key="item">
<input type="number" @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: 4
}
},
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
!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{
border-bottom: 1px solid #D6D6D6;
width: 15%;
height: 0;
padding-bottom:20%;
position: relative;
input{
position: absolute;
width: 100%;
height: 100%;
text-align: center;
transition: all 0.3s;
font-size: 7vw;
color: #333333;
}
}
input:focus{
border-bottom: 1px solid #666666;
}
}
</style>
更多推荐
已为社区贡献16条内容
所有评论(0)