vue3 setup 语法 + ant-vue-design 实现验证码输入框效果 有光标效果
新增一个组件input-code.vue
, 然后复制下面全部组件代码就行
效果图如下
组件代码:
// input-code.vue
<template>
<div>
<div class="input-code">
<span class="code" v-for="(item, index) in count" :key="index">
<span>{{ getReadNum(index) }}</span>
<span v-if="index === currentIndex && isFocused" class="cursor"></span>
</span>
<a-input
type="password"
class="input"
:maxlength="count"
v-model:value="codeValue"
@input="updateCursor"
@keydown="handleKeyDown"
@focus="isFocused = true"
@blur="isFocused = false"
ref="inputRef"
/>
</div>
</div>
</template>
<script setup>
import { ref, watch, onMounted } from 'vue';
const props = defineProps({
// 验证码数量 长度
count: {
type: Number,
default: 6
},
// input 值
value: {
type: String,
default: ''
},
// 自动获取焦点
autoFocus: {
type: Boolean,
default: false
}
});
const emit = defineEmits(['update:value']);
const codeValue = ref('');
const currentIndex = ref(0);
const isFocused = ref(false); // 控制光标闪烁的状态
const inputRef = ref(null); // 用于引用输入框
const getReadNum = (index) => {
let arr = String(codeValue.value)
.split('')
.map(() => '*');
return arr[index];
};
const updateCursor = () => {
currentIndex.value = codeValue.value.length; // 更新光标位置
emit('update:value', codeValue.value);
};
const handleKeyDown = (event) => {
if (event.ctrlKey && event.key === 'a') {
event.preventDefault(); // 阻止 Ctrl + A 全选
}
};
watch(
() => props.value,
(val) => {
codeValue.value = val;
},
{ immediate: true }
);
onMounted(() => {
if (props.autoFocus) {
inputRef.value.focus(); // 自动获取焦点
}
});
</script>
<style lang="less" scoped>
.input-code {
position: relative;
width: 450px;
margin: 20px auto;
display: flex;
align-items: center;
vertical-align: baseline;
justify-content: space-between;
.code {
display: block;
height: 65px;
width: 65px;
background-color: rgb(51, 146, 153);
border-radius: 5px;
color: #fff;
font-size: 28px;
display: flex;
align-items: center;
justify-content: center;
position: relative;
.cursor {
position: absolute;
width: 1px;
height: 55%;
background-color: #fff;
animation: blink 1s step-end infinite; /* 闪烁效果 */
top: 50%;
transform: translate(-50%, -50%);
}
span {
position: relative;
top: 6px;
font-size: 40px;
}
}
.input {
position: absolute;
height: 65px;
opacity: 0;
}
}
@keyframes blink {
0%,
100% {
opacity: 1;
}
50% {
opacity: 0;
}
}
</style>
使用组件
// index.vue
<template>
<div>
<input-code v-model:value="codeValue" :autoFocus="true" />
</div>
</template>
<script setup>
import { ref } from 'vue';
import InputCode from './components/input-code.vue';
const codeValue = ref('');
</script>