纯前端实现一个输入验证码实例
项目需求需要实现一个用户输入验证码,并且输入完第一个数字后光标自动移动到下一个,当删除后一个数字时,鼠标光标则需要向前移动一格
html代码片段及样式 (该项目中我使用的是vue2+vant)
下面展示一些 内联代码片
。
<div class="increaseAmount">
<div>验证码已发送至{{ maskPhoneNumber(userInfo.phone) }}</div>
<div class="code-input-container">
<input
v-for="(item, index) in codeLength"
:key="index"
type="text"
maxlength="1"
inputmode="numeric"
pattern="\d*"
@input="handleInput($event, index)"
@keydown="handleKeyDown($event, index)"
@focus="handleFocus(index)"
ref="codeInputs"
:class="{ 'focused': focusedIndex === index }"
/>
</div>
<div class="countdown" v-if="countdown >= 0">倒计时{{ countdown }}s</div>
<div class='confirmBtn'>
<van-button color="#FF5959" round block :disabled="flagBtn"
style="box-shadow: 0px 10px 10px 0px rgba(233, 70, 50, 0.2);" @click="confirmSubmission">确认</van-button>
</div>
</div>
<style>
.increaseAmount {
display: flex;
flex-direction: column;
align-items: center;
padding: 3vw;
font-size: 3.5vw;
}
.code-input-container {
display: flex;
justify-content: space-between;
margin-top: 6vw;
width: 90%;
height: 10vw;
}
.code-input-container input {
width: 22%;
height: 100%;
text-align: center;
font-size: 4vw;
border: 1px solid #fff;
border-radius: 4px;
margin: 0 5px;
}
.countdown {
color: #FF6161;
margin: 7vw 0 0 0;
}
.confirmBtn {
width: 70%;
margin: 9vw auto 4vw;
}
</style>
js代码如下
data() {
return {
verificationCodeShow: false,
codeLength: 5, // 验证码长度
focusedIndex: null, // 当前聚焦的输入框索引
codeValues: ['', '', '', '', ''], // 存储验证码值
countdown: 60,
timer: null,
flagBtn: true
}
},
handleInput(event, index) {
const value = event.target.value;
if (/^\d$/.test(value)) {
this.codeValues[index] = value;
if (index < this.codeLength - 1) {
this.$refs.codeInputs[index + 1].focus();
}
} else {
this.codeValues[index] = '';
event.target.value = ''; // 立即清空当前输入框
// 如果用户尝试输入非数字字符,保持焦点不变
this.$nextTick(() => {
this.$refs.codeInputs[index].focus();
});
}
this.btnType()
},
handleKeyDown(event, index) {
// 检测 删除 键
if (event.key === "Backspace") {
event.preventDefault(); // 立即阻止默认行为以避免不必要的删除
if (this.codeValues[index]) {
// 如果当前输入框有值,则清除它
this.codeValues[index] = '';
event.target.value = ''; // 立即清空当前输入框
}
// 尝试将焦点移动到前一个输入框
if (index > 0) {
this.$refs.codeInputs[index - 1].focus();
} else {
// 如果是第一个输入框,则保持焦点在此处
this.$refs.codeInputs[0].focus();
}
}
this.btnType()
},
handleFocus(index) {
this.focusedIndex = index;
},
clearCodeInputs() {
this.codeValues.fill('');
this.$nextTick(() => {
if (this.$refs.codeInputs && this.$refs.codeInputs.length) {
this.$refs.codeInputs[0].focus();
}
});
},
// 校验当前输入的验证码是否全部输入(是否存在空格)
btnType() {
var flag = this.codeValues.every(value => value.trim() !== '')
flag == true ? this.flagBtn = false : this.flagBtn = true
},