VUE+CSS变量实现验证码输入框
还是不会插图而且有小bug,欢迎大佬提出宝贵意见,仍然是使用input框
1.html部分
<template>
<div class="box">
<!-- 循环生成input 绑定keyup事件传入事件源,以及第几个input框 获取焦点的输入框添加高亮 -->
<input
:style="{ borderBottomColor: currentIndex === el ? 'var(--border-active-color)' : 'var(--border-deactive-color)' }"
class="inp" @focus="currentIndex = el" @keyup="keyUpEvent($event, el)" type="text" maxlength="1"
v-for="el in inpAry" :key="el" />
</div>
</template>
2.CSS部分,还是设置了CSS变量
<style scoped>
.box {
/* 各种样式的css变量 */
--custom-box-width: 200px;
--custom-box-height: 50px;
--custom-font-size: 18px;
--custom-font-color: purple;
--border-bottom-width: 1px;
--border-code-style: none;
--border-deactive-color: grey;
--border-active-color: hotpink;
--border-radius: 0;
--border-default-width: 20px;
width: calc(var(--border-default-width) * 10);
height: var(--custom-box-height);
display: flex;
justify-content: space-evenly;
align-items: center;
}
.inp {
width: calc(var(--custom-box-width) * 0.1);
height: calc(var(--custom-box-height) * 0.7);
line-height: calc(var(--custom-box-height) * 0.7);
border: var(--border-code-style);
outline: none;
text-align: center;
border-bottom: 1px solid red;
border-bottom-width: var(--border-bottom-width);
border-bottom-color: var(--border-deactive-color);
font-size: var(--custom-font-size);
color: var(--custom-font-color);
border-radius: var(--border-radius);
}
</style>
3.js部分
<script lang="ts" setup>
import { ref, onMounted, watch } from 'vue';
// 控制高亮
const currentIndex = ref<number>(-1)
// 存储输入的数值
const totalCode = ref<any[]>([])
// 存储输入框个数以及位置的数组
const inpAry = ref<Array<any>>([]);
// 回传验证码的事件
const emit = defineEmits<{ (e: 'onFinish', data: Array<any>): void }>()
// 定义默认输入验证码位数
const props = defineProps({
count: {
type: Number,
default: 4
}
})
// 挂载后生成数组用于渲染input框
onMounted(() => {
for (let index = 0; index < props.count; index++) {
inpAry.value.push(index)
}
})
//keyup回调函数
const keyUpEvent = (e: KeyboardEvent, i: number) => {
let code = Number(e.key)//转number
if (code >= 0 && code <= 9) {
// 存储对应位置的验证码
totalCode.value[i] = code
let next = (e as any).target.nextElementSibling
// 如果有下一个元素,下一个兄弟元素获取焦点
if (next) {
next.focus()
}
} else {
//否则设置为空字符串
(e as any).target.value = ''
}
let { key } = e
//如果是删除或者回退键存储该验证码的下标替换为空字符串
if (key === 'Backspace' || key === 'Delete') {
totalCode.value[i] = ''
const prev = (e as any).target.previousElementSibling;
if (prev) prev.focus();
}
console.log(totalCode.value);
}
//watch监听验证码数组长度,数组不包含空字符串且长度等于4回传验证码数组
watch(() => totalCode.value.length, (newval: number) => {
if (!totalCode.value.includes('') && newval === 4) {
emit('onFinish', totalCode.value)
}
})
原谅我的any,确实定义不明白了,而且实现双向绑定有点困难,已输入的部分再次输入,无法修改现有值,但是回传的
数据值会发生变化,回传的数据是数组,可以按需配置,CSS变量的定义逻辑有点小混乱,被输入值的问题卡住了,欢迎
大佬斧正,图依旧是不会插,可以复制代码试一试