六格验证码填充简单思路
html
<div id="verificationCode">
<input type="text" maxlength="1" />
<input type="text" maxlength="1" />
<input type="text" maxlength="1" />
<input type="text" maxlength="1" />
<input type="text" maxlength="1" />
<input type="text" maxlength="1" />
</div>
css
#verificationCode input {
width: 40px;
height: 40px;
font-size: 24px;
text-align: center;
}
js
const verificationCodeInputs = document.querySelectorAll('#verificationCode input');
verificationCodeInputs.forEach((input, index) => {
input.addEventListener('input', (e) => {
const currentInput = e.target;
const nextInput = verificationCodeInputs[index + 1];
const previousInput = verificationCodeInputs[index - 1];
if (currentInput.value !== '') {
currentInput.value = currentInput.value[0]; // Only allow single character input
if (nextInput && currentInput.value !== '') {
nextInput.focus(); // Move focus to the next input box
}
} else if (previousInput) {
previousInput.focus(); // Move focus to the previous input box
}
});
});
vue组件 隐藏输入框方式
<template>
<!-- 验证码输入框 -->
<view>
<view class="flex-box">
<input :value="inputValue" type="number" :adjust-position="false" :focus="autoFocus" :maxlength="codeNumber"
class="hide-input" @input="getVal" />
<view class="section">
<block v-for="(item, index) in ranges" :key="index">
<view
:class="['item', { active: codeIndex === item, middle: type === 'middle', bottom: type === 'bottom', box: type === 'box' }]">
<view class="line" v-if="type !== 'middle'"></view>
<view v-if="type === 'middle' && codeIndex <= item" class="bottom-line"></view>
<block v-if="passwordMode && codeArr.length >= item">
<text class="dot">*</text>
</block>
<block v-else> {{ codeArr[index] ? codeArr[index] : ''}}</block>
</view>
</block>
</view>
</view>
</view>
</template>
<script>
export default {
props: {
itemWidth: {
type: Number,
default: 80
},
itemHeight: {
type: Number,
default: 105
},
// 验证码值
value: {
type: String,
default: ''
},
// 4 | 6
codeNumber: {
type: Number,
default: 6
},
autoFocus: {
type: Boolean,
default: true
},
// 密码模式,用.替代
passwordMode: {
type: Boolean,
default: false
},
// middle-middle line, bottom-bottom line, box-square box
type: {
type: String,
default: "box"
},
itemSpace: {
type: Number,
default: 20
}
},
watch: {
codeNumber: {
immediate: true,
handler: function(newV) {
if (newV === 6) {
this.ranges = [1, 2, 3, 4, 5, 6]
} else {
this.ranges = [1, 2, 3, 4]
}
}
},
value: {
immediate: true,
handler: function(newV) {
if (newV !== this.inputValue) {
this.inputValue = newV
this.toMakeAndCheck(newV)
}
}
}
},
data() {
return {
inputValue: '',
codeIndex: 1,
codeArr: [],
ranges: [1, 2, 3, 4]
}
},
methods: {
getVal(e) {
const val = e.detail.value
this.inputValue = val
this.$emit('input', val)
this.toMakeAndCheck(val)
},
toMakeAndCheck(val) {
const arr = val.split('')
this.codeIndex = arr.length + 1
this.codeArr = arr
if (this.codeIndex > Number(this.codeNumber)) {
this.$emit('finish', this.codeArr.join(''))
}
},
set(val) {
this.inputValue = val
this.toMakeAndCheck(val)
},
clear() {
this.inputValue = ''
this.codeArr = []
this.codeIndex = 1
}
}
}
</script>
<style lang="scss" scoped>
@keyframes twinkling {
0% {
opacity: 0.2;
}
50% {
opacity: 0.5;
}
100% {
opacity: 0.2;
}
}
.hide-input {
position: absolute;
top: 0;
left: -100%;
width: 200%;
height: 100%;
text-align: left;
z-index: 9;
opacity: 1;
}
.section {
display: grid;
grid-template-columns: repeat(6, 1fr);
column-gap: 26rpx;
>view {
position: relative;
height: 112rpx;
font-size: 48rpx;
font-weight: bold;
background: #F5F5F5;
color: #000000;
line-height: 112rpx;
border-radius: 10rpx;
text-align: center;
}
}
.flex-box .item:last-child {
margin-right: 0;
}
.flex-box .middle {
border: none;
}
.flex-box .bottom {
box-sizing: border-box;
}
.flex-box .active {}
.flex-box .active .line {
display: block;
}
.flex-box .line {
display: none;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 2upx;
height: 40upx;
background: #333333;
animation: twinkling 1s infinite ease;
}
.flex-box .dot {
font-size: 80upx;
line-height: 40upx;
}
.flex-box .bottom-line {
height: 2rpx;
background: #000000;
width: 80%;
position: absolute;
border-radius: 4rpx;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
</style>