uniapp 验证码输入框
经常会有这样的需求,验证码只能输入数字,自动跳转到下一个数字位置,然后删除时自动跳转到上一个位置。
比如说需要输入6位数字的验证码,起初是打算用6个输入框来做,然后每个输入框有两个属性来控制,value和isFocus, 用来控制当前值以及当前框是不是获得焦点
不过这个在微信(安卓)端,由于焦点切换,数字键盘会有收起和弹出的动作,用起来就会闪动,网上有大神说只用一个input框来做,基于这个思路尝试了一下,个人觉得确实好用,希望对你也有用
先来个图
代码在这里
<template>
<view class="container">
<view class="sub-title">
<text>验证码</text>
</view>
<view class="yy">
<view class="desc">验证码已发送至您尾号{{phoneNumber.slice(-4)}}的手机号</view>
<view class="outer">
<view class="wrap">
<view v-for="(item, key) in code" :key="key" class="inner" @click="handleCodeClick(key)">
<view class="item">
{{item.num}}
</view>
</view>
<input v-if="inputFocus" type="number" inputmode="numeric" class="code-input" :focus="inputFocus"
@blur="inputFocus=false" @input="inputFinish($event)" v-model="inputValue"
:style="{left:activeIndex*width+'px'}" />
</view>
</view>
</view>
</view>
</template>
<script>
const keyCodeValue = {
"48": "0",
"49": "1",
"50": "2",
"51": "3",
"52": "4",
"53": "5",
"54": "6",
"55": "7",
"56": "8",
"57": "9"
}
export default {
data() {
return {
phoneNumber: "13800000000",
width: 60,
activeIndex: 0,
inputValue: '',
inputFocus: false,
code: [{
num: '',
},
{
num: '',
},
{
num: '',
},
{
num: '',
},
{
num: '',
},
{
num: '',
},
],
}
},
methods: {
handleConfirm() {
const str = this.code.map(({
num
}) => num).join("")
if (str.length !== 6) {
return this.$modal.msg("请输入完整验证码");
}
this.$emit("callback", str)
},
handleCodeClick(index) {
this.code[index].num = ""
this.activeIndex = index
this.inputFocus = true
},
inputFinish(e) {
const index = this.activeIndex
const {
keyCode,
value
} = e.detail;
if (keyCode === 8) {
if (this.code[index]) this.code[index].num = '';
if (index > 0) {
this.code[index - 1].num = ''
this.activeIndex--
}
return;
}
const v = keyCodeValue[keyCode]
if (v) {
this.code[index].num = v
} else {
this.code[index].num = ''
return;
}
if (index + 1 == this.code.length) {
this.activeIndex = -20
this.inputFocus = false
} else {
this.activeIndex++
}
this.$nextTick(() => {
this.inputValue = ""
if (this.code[this.activeIndex]) {
this.code[this.activeIndex].num = ""
}
})
},
}
}
</script>
<style lang="scss" scoped>
.container {
width: 750rpx;
background: #FFFFFF;
border-radius: 40rpx 40rpx 0rpx 0rpx;
opacity: 1;
overflow: hidden;
padding: 200rpx 0;
}
.yy {
text-align: center;
.desc {
padding-top: 40rpx;
}
.wrap {
display: flex;
align-items: center;
margin-top: 50rpx;
position: relative;
.item {
width: 50px;
height: 50px;
line-height: 50px;
background-color: #eee;
border-radius: 5px;
}
.inner {
padding: 0px 5px;
box-sizing: border-box;
}
.code-input {
position: absolute;
top: 0;
width: 60px;
height: 50px;
line-height: 50px;
// background-color: #eee;
border-radius: 5px;
// border: 1px solid red;
box-sizing: border-box;
z-index: 3;
}
}
}
.sub-title {
height: 48rpx;
font-size: 34rpx;
font-weight: 500;
color: rgba(0, 0, 0, 0.9);
line-height: 40rpx;
position: relative;
text-align: center;
padding-top: 40rpx;
}
.outer {
display: flex;
justify-content: center;
align-items: center;
}
</style>