<template>
<div id="app">
<div class="captcha">
<input v-for="(c, index) in ct" :key="index"
onkeyup="value=value.replace(/[^\d]/g,'')"
oninput="value=value.replace(/[^\d]/g,'')"
type="number" v-model="ct[index]" ref="input"
:style="{borderBottomColor: index <= cIndex ? '#333' : ''}"
@input="e => {onInput(e.target.value, index)}"
@keydown.delete="e=>{onKeydown(e.target.value, index)}"
@focus="onFocus"
:disabled="loading"
>
</div>
<p>{{msg}}</p>
</div>
</template>
<script>
export default {
name: '',
data() {
return {
ct: ['', '', '', '', '', ''],
loading: false,
msg: '',
}
},
computed: {
ctSize() {
return this.ct.length;
},
cIndex() {
let i = this.ct.findIndex(item => item === '');
i = (i + this.ctSize) % this.ctSize;
return i;
},
lastCode() {
return this.ct[this.ctSize - 1];
}
},
watch: {
cIndex() {
this.resetCaret();
},
lastCode(val) {
if (val) {
console.log('this.ctSize', this.ctSize)
this.$refs.input[this.ctSize - 1].blur();
this.sendCaptcha();
}
}
},
mounted() {
this.resetCaret();
},
methods: {
onInput(val, index) {
this.msg = ''
val = val.replace(/\s/g, '');
if (index == this.ctSize - 1) {
this.ct[this.ctSize - 1] = val[0];
} else if(val.length > 1) {
let i = index;
for (i = index; i < this.ctSize && i - index < val.length; i++) {
this.ct[i] = val[i];
}
this.resetCaret();
}
},
resetCaret() {
this.$refs.input[this.ctSize-1].focus();
},
onFocus() {
let index = this.ct.findIndex(item => item === '');
index = (index + this.ctSize) % this.ctSize;
console.log(this.$refs.input)
this.$refs.input[index].focus();
},
onKeydown(val, index) {
if (val === '') {
if (index > 0) {
this.ct[index - 1] = '';
this.$refs.input[index - 1].focus();
}
}
},
sendCaptcha() {
console.log();
this.msg = `发送验证码到服务器:${this.ct.join('')}`;
this.loading = true;
setTimeout(() => {
this.msg = ('验证码错误')
this.loading = false;
this.$nextTick(() => {
this.reset();
})
}, 3000)
},
reset() {
this.ct = this.ct.map(item => '');
this.resetCaret();
}
}
}
</script>
<style lang="scss" scoped>
.captcha {
display: flex;
justify-content: center;
margin-top: 2.5rem;
}
input {
margin-right: 1.25rem;
width: 1.25rem;
text-align: center;
border: none;
border-bottom: .0625rem solid #eee;
font-size: .75rem;
outline: none;
}
input:last-of-type {
margin-right: 0;
}
input:disabled {
color: #000;
background-color: #fff;
}
.msg {
text-align: center;
}
</style>