模板部分 (<template>
)
<template>
<div class="verifyCode">
<div class="inputList" ref="inputListRef">
<el-input
v-for="(item, index) in code"
:key="index"
v-model="item.number"
style="width: 30px"
maxlength="1"
@keyup.delete="handleBackspace(index)"
@input="handleInput(index)"
@paste="handlePaste($event, index)"
:class="{ focused: item.isFocused }"
ref="inputRefs"
/>
<div class="solid">—</div>
</div>
</div>
</template>
v-for
: 遍历code
数组,为每个验证码数字创建一个el-input
输入框。v-model
: 双向绑定输入框的值到code
数组中对应元素的number
属性。maxlength="1"
: 限制每个输入框只能输入一个字符。@keyup.delete
: 监听删除键事件,调用handleBackspace
函数处理删除逻辑。@input
: 监听输入事件,调用handleInput
函数处理输入逻辑。@paste
: 监听粘贴事件,调用handlePaste
函数处理粘贴逻辑。:class="{ focused: item.isFocused }"
: 根据isFocused
属性动态添加focused
类,用于样式变化。ref="inputRefs"
: 设置引用,便于在脚本中访问DOM元素。
脚本部分 (<script setup>
)
import { reactive, ref, onMounted, nextTick } from 'vue'
const inputListRef = ref(null)
const inputRefs = ref([])
const code = reactive([
{ number: '', isFocused: false },
{ number: '', isFocused: false },
{ number: '', isFocused: false },
{ number: '', isFocused: false },
{ number: '', isFocused: false },
{ number: '', isFocused: false }
])
onMounted(() => {
// 默认聚焦第一个输入框
focusInput(0)
})
// 聚焦到指定的输入框
const focusInput = (index) => {
nextTick(() => {
const input = inputRefs.value[index].$el.querySelector('input')
input.focus()
code.forEach((item, i) => {
item.isFocused = i === index
})
})
}
// 处理删除事件
const handleBackspace = (index) => {
if (code[index].number === '' && index > 0) {
focusInput(index - 1)
} else {
code[index].number = ''
}
}
// 处理输入事件
const handleInput = (index) => {
if (code[index].number.length > 0 && index < 5) {
focusInput(index + 1)
}
}
// 处理粘贴事件
const handlePaste = (event, index) => {
event.preventDefault()
const pastedText = event.clipboardData.getData('text').match(/\d/g)
if (pastedText && pastedText.length <= 6) {
pastedText.forEach((num, i) => {
code[i].number = num
if (i < 5) {
focusInput(i + 1)
}
})
}
}
reactive
: 创建响应式数据code
,存储验证码的每个数字及其聚焦状态。ref
: 创建引用inputListRef
和inputRefs
,分别用于访问输入列表和单个输入框的DOM元素。onMounted
: 组件挂载后,默认聚焦到第一个输入框。focusInput
: 函数用于聚焦到指定索引的输入框,并更新isFocused
状态。handleBackspace
: 函数处理删除逻辑,如果当前输入框为空且不是第一个,则聚焦到前一个输入框;否则清空当前输入框的内容。handleInput
: 函数处理输入逻辑,如果当前输入框有内容且不是最后一个,则聚焦到下一个输入框。handlePaste
: 函数处理粘贴逻辑,从剪贴板获取文本,提取数字,并填充到输入框中,同时管理聚焦状态。
样式部分 (<style scoped lang="scss">
)
.inputList {
position: relative;
.el-input {
margin-right: 10px;
&.focused {
border-color: #409eff;
}
}
:deep(.el-input:nth-child(3)) {
margin-right: 40px;
}
.solid {
position: absolute;
top: 3px;
left: 120px;
}
}
最后效果: