vue组件
<template>
<div class="verifyCode mt-24">
<div class="header">
<span class="logo inline-block mr-6 w-[26px] h-[26px] bg-black-0"></span>
<span class="title text-[22px] font-semibold"> {{ title }}</span>
</div>
<div class="desc text-sm mt-6">
{{ desc }}
</div>
<div class="main flex justify-between items-center">
<div class="number">
<div class="input-box flex-1">
<div class="input-content" @keydown="keydown" @keyup="keyup" @paste="paste" @mousewheel="mousewheel"
@input="inputEvent">
<input max="9" min="0" maxlength="1" data-index="0" v-model.trim.number="input[0]" type="number"
:class="isError || isExpired ? 'error' : 'default'" />
<input max="9" min="0" maxlength="1" data-index="1" v-model.trim.number="input[1]" type="number"
:class="isError || isExpired ? 'error' : 'default'" />
<input max="9" min="0" maxlength="1" data-index="2" v-model.trim.number="input[2]" type="number"
:class="isError || isExpired ? 'error' : 'default'" />
<input max="9" min="0" maxlength="1" data-index="3" v-model.trim.number="input[3]" type="number"
:class="isError || isExpired ? 'error' : 'default'" />
<input max="9" min="0" maxlength="1" data-index="4" v-model.trim.number="input[4]" type="number"
:class="isError || isExpired ? 'error' : 'default'" />
<input max="9" min="0" maxlength="1" data-index="5" v-model.trim.number="input[5]" type="number"
:class="isError || isExpired ? 'error' : 'default'" />
</div>
</div>
</div>
<div v-show="isCodeShow">
<div v-show="sendMsg.length >= 7" @click="handleReSend"
class="resend mt-4 w-[96px] h-9 cursor-pointer leading-9 text-center border-2 border-[#000] text-sm font-semibold rounded-[16px]">
Get code
</div>
<div v-show="parseInt(sendMsg) >= 1"
class="resend mt-4 w-[96px] h-9 leading-9 text-center text-sm font-semibold ">
{{ sendMsg }}s
</div>
</div>
</div>
<div class="mailCode mt-3 text-[13px] font-medium text-[#868D9A]">
{{ mark }}
</div>
<!-- 错误 -->
<div v-show="isError" class="errCode mt-3 text-[13px] font-medium text-[#F36343]">
Verification code error, please try again
</div>
<!-- 过期 -->
<div v-show="isExpired" class="errCode mt-3 text-[13px] font-medium text-[#F36343]">
The verification code has expired, please obtain it again
</div>
<!-- 忘记密码 -->
<div v-show="isResetPassword" class="text-[#868D9A] text-[13px] mt-3 cursor-pointer">
Forget number
<svg xmlns="http://www.w3.org/2000/svg" width="6" height="10" viewBox="0 0 6 10" fill="none">
<rect width="6.01783" height="1.3373" rx="0.668648"
transform="matrix(-0.707108 0.707106 -0.707108 -0.707106 6 5.04492)" fill="#A8AAAE" />
<rect width="6.01783" height="1.3373" rx="0.668648"
transform="matrix(-0.707108 -0.707106 0.707108 -0.707106 5.05469 5.83496)" fill="#A8AAAE" />
</svg>
</div>
</div>
</template>
<script>
let TIME_COUNT = 60; // 设置一个全局的倒计时的时间
export default {
props: {
"isCodeShow": {
type: Boolean,
default: () => {
return false;
}
},
"isResetPassword": {
type: Boolean,
default: () => {
return false;
}
},
"title": {
type: String,
default: () => {
return 'defalut title';
}
},
"desc": {
type: String,
default: () => {
return 'defalut desc';
}
},
"mark": {
type: String,
default: () => {
return '';
}
}
},
data() {
return {
input: [],
sendMsg: "",
timer: null,
isError: false,
isExpired: false,
}
},
created() {
this.input = new Array(6).fill('');
if(this.getLocalStorage('TIME_COUNT')){
this.handleReSend()
} else {
this.sendMsg = 'Get code'
}
},
methods: {
// 设置缓存
setLocalStorage(key, value) {
try {
window.localStorage.setItem(key, JSON.stringify(value));
} catch (error) {
// 处理缓存设置失败的情况
console.error('设置缓存失败:', error);
}
},
// 获取缓存
getLocalStorage(key) {
try {
const value = window.localStorage.getItem(key);
return value ? JSON.parse(value) : null;
} catch (error) {
// 处理缓存获取失败的情况
console.error('获取缓存失败:', error);
return null;
}
},
removeLocalStorage(key) {
try {
window.localStorage.removeItem(key);
} catch (error) {
// 处理缓存删除失败的情况
console.error('删除缓存失败:', error);
}
},
// 解决一个输入框输入多个字符
inputEvent(e) {
var index = e.target.dataset.index * 1
var el = e.target
el.value = el.value
.replace(/Digit|Numpad/i, '')
.replace(/1/g, '')
.slice(0, 1)
this.input[index] = el.value
},
keydown(e) {
var index = e.target.dataset.index * 1
var el = e.target
if (e.key === 'Backspace') {
if (this.input[index] && this.input[index].length > 0) {
this.input[index] = ''
} else {
if (el.previousElementSibling) {
el.previousElementSibling.focus()
this.input[index - 1] = ''
}
}
} else if (e.key === 'Delete') {
if (this.input[index].length > 0) {
this.input[index] = ''
} else {
if (el.nextElementSibling) {
this.input[(index = 1)] = ''
}
}
if (el.nextElementSibling) {
el.nextElementSibling.focus()
}
} else if (e.key === 'Home') {
el.parentElement.children[0] && el.parentElement.children[0].focus()
} else if (e.key === 'End') {
el.parentElement.children[this.input.length - 1] &&
el.parentElement.children[this.input.length - 1].focus()
} else if (e.key === 'ArrowLeft') {
if (el.previousElementSibling) {
el.previousElementSibling.focus()
}
} else if (e.key === 'ArrowRight') {
if (el.nextElementSibling) {
el.nextElementSibling.focus()
}
} else if (e.key === 'ArrowUp') {
if (this.input[index] * 1 < 9) {
this.input[index] = (this.input[index] * 1 + 1).toString()
}
} else if (e.key === 'ArrowDown') {
if (this.input[index] * 1 > 0) {
this.input[index] = (this.input[index] * 1 - 1).toString()
}
}
},
keyup(e) {
var index = e.target.dataset.index * 1
var el = e.target
// 解决输入e的问题
el.value = el.value
.replace(/Digit|Numpad/i, '')
.replace(/1/g, '')
.slice(0, 1)
if (/Digit|Numpad/i.test(e.code)) {
// 必须在这里符直,否则输入框会是空值
this.input[index] = e.code.replace(/Digit|Numpad/i, '')
el.nextElementSibling && el.nextElementSibling.focus()
if (index === 5) {
if (this.input.join('').length === 6) {
document.activeElement.blur()
}
}
} else {
if (this.input[index] === '') {
this.input[index] = ''
}
}
this.$emit('complete', this.input.slice());
},
mousewheel(e) {
var index = e.target.dataset.index
if (e.wheelDelta > 0) {
if (this.input[index] * 1 < 9) {
this.input[index] = (this.input[index] * 1 + 1).toString()
}
} else if (e.wheelDelta < 0) {
if (this.input[index] * 1 > 0) {
this.input[index] = (this.input[index] * 1 - 1).toString()
}
} else if (e.key === 'Enter') {
if (this.input.join('').length === 6) {
document.activeElement.blur()
this.$emit('complete', this.input.slice())
}
}
},
paste(e) {
// 当进行粘贴时
e.clipboardData.items[0].getAsString((str) => {
if (str.toString().length === 6) {
document.activeElement.blur();
this.input = str.split('');
this.$emit('complete', this.input.slice())
} else {
// 如果粘贴内容不合规,清除所有内容
this.input[0] = new Array(6)
}
})
},
handleReSend() {
// 模拟生成code
this.sendMsg = this.getLocalStorage('TIME_COUNT') || TIME_COUNT;
this.timer = setInterval(() => {
if (this.sendMsg <= 1) {
clearInterval(this.timer)
this.removeLocalStorage('TIME_COUNT')
this.sendMsg = "Get code"
return
}
this.sendMsg -= 1;
this.setLocalStorage('TIME_COUNT',this.sendMsg)
}, 1000)
},
getCode() {
let resultArray = this.input.filter(item => {
return item != '' && item >= 0
})
if (resultArray.length == 6) {
let originStr = resultArray.toString().replace(/,/g, '')
return originStr;
} else {
this.$message.error('请检查输入的数据!')
}
}
}
}
</script>
<style>
.input-box .input-content {
margin-top: 15px;
display: flex;
align-items: center;
justify-content: space-between;
}
.input-box .input-content input {
color: inherit;
font-family: inherit;
border: 0;
outline: 0;
height: 42px;
width: 42px;
line-height: 42px;
border-radius: 12px;
font-size: 22px;
text-align: center;
margin-right: 14px;
}
.error {
color: #F36343 !important;
background: #f7e6e5 !important;
}
.default {
color: #000;
background: #F2F4F5;
}
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
appearance: none;
margin: 0;
}
</style>
父组件使用
<ValidCode ref="ValidCodeMail" v-bind="ValidCodeMailProps" />
data(){
ValidCodeMailProps: {
isCodeShow: true,
title: "mailbox verification",
desc: "Please enter your email verification code",
mark: "[email protected]",
},
}
// 获取code
const ValidCodeGoogleCode = this.$refs.ValidCodeGoogle.getCode();
标签:el,缓存,index,验证码,else,倒计时,key,error,input
From: https://www.cnblogs.com/brujie/p/17911779.html