Vue 实现输入框短信验证码功能

实现功能:

  • 输入数字后,焦点自动跳转到下一个 input 上
  • 按下删除键后,焦点自动跳转到上一个 input 上
  • 按下 del 键,可以删除且焦点自动跳转到下一个 input 上
  • 左右键可以移动焦点
  • 粘贴长度为 6的文本后,自动将复制的文本赋值到 input 上

效果

在这里插入图片描述


代码

<template>
	<div class="g-remove-check-code">
		<p class="g-remove-check-code_title">已向绑定微信发送验证码</p>
		<div class="g-remove-check-code_content"
		     @keyup="fnCheckCodeKeyup"
		     @keydown="fnCheckCodeKeydown"
		     @paste="fnCheckCodeKeyPaste"
		     @input="fnCheckCodeInputEvent"
		>
		    <input :class="{'g-code-input_color': aCheckCodeInputComputed[0] !== ''}" max="9" min="0" maxlength="1" data-index="0" v-model.trim.number="aCheckCodeInputComputed[0]" type="number" ref="firstInputRef" />
		    <input :class="{'g-code-input_color': aCheckCodeInputComputed[1] !== ''}" max="9" min="0" maxlength="1" data-index="1" v-model.trim.number="aCheckCodeInputComputed[1]" type="number" />
		    <input :class="{'g-code-input_color': aCheckCodeInputComputed[2] !== ''}" max="9" min="0" maxlength="1" data-index="2" v-model.trim.number="aCheckCodeInputComputed[2]" type="number" />
		    <input :class="{'g-code-input_color': aCheckCodeInputComputed[3] !== ''}" max="9" min="0" maxlength="1" data-index="3" v-model.trim.number="aCheckCodeInputComputed[3]" type="number" />
		    <input :class="{'g-code-input_color': aCheckCodeInputComputed[4] !== ''}" max="9" min="0" maxlength="1" data-index="4" v-model.trim.number="aCheckCodeInputComputed[4]" type="number" />
		    <input :class="{'g-code-input_color': aCheckCodeInputComputed[5] !== ''}" max="9" min="0" maxlength="1" data-index="5" v-model.trim.number="aCheckCodeInputComputed[5]" type="number" />
		</div>
		<p class="g-remove-check-code_tip">请输入六位数验证码</p>
</div>
</template>

<script>
	export default {
		data() {
			return {
				aCheckCodeInput: ['','','','','',''], 	// 存储输入验证码内容
                aCheckCodePasteResult: [], 				// 粘贴的验证码
			}	
		},
		computed: {
            // 验证码计算属性
            aCheckCodeInputComputed() {
                if(this.aCheckCodePasteResult.length === 6) {
                    return this.aCheckCodePasteResult;
                } else if (this.aCheckCodeInput && Array.isArray(this.aCheckCodeInput) && this.aCheckCodeInput.length === 6) {
                    return this.aCheckCodeInput;
                } else if (/^\d{6}$/.test(this.aCheckCodeInput.toString())) {
                    return this.aCheckCodeInput.toString().split("");
                } else {
                    return new Array(6);
                }
            },
		},
		methods: {
			// 输入验证码,更新验证码数据
            fnCheckCodeKeyup(e) {
                let index = e.target.dataset.index * 1;
                let el = e.target;
                // 解决输入e的问题
                el.value = el.value
                    .replace(/Digit|Numpad/i, "")
                    .slice(0, 1);
                if (/Digit|Numpad/i.test(e.code)) {
                    // 必须在这里赋值,否则输入框会是空值
                    this.aCheckCodeInput.splice(index, 1, e.code.replace(/Digit|Numpad/i, ""));
                    el.nextElementSibling && el.nextElementSibling.focus();
                    if (index === 5) {
                        if (this.aCheckCodeInput.join("").length === 6)  document.activeElement.blur();
                    }
                }
            },
            // 输入验证码,检测位置变化
            fnCheckCodeKeydown(e) {
                let index = e.target.dataset.index * 1;
                let el = e.target;
                if (e.key === "Backspace") {
                    if (this.aCheckCodeInput[index].length > 0) {
                        this.aCheckCodeInput.splice(index, 1, '');
                    } else {
                        if (el.previousElementSibling) {
                            el.previousElementSibling.focus();
                            this.aCheckCodeInput[index - 1] = '';
                        }
                    }
                } else if(e.key === 'Delete') {
                    if (this.aCheckCodeInput[index].length > 0) {
                        this.aCheckCodeInput.splice(index, 1, '');
                    } else {
                        if(el.nextElementSibling) {
                            el.nextElementSibling.focus();
                            this.aCheckCodeInput[++index] = '';
                        }
                    }
                } else if (e.key === "Home") {
                    el.parentElement.children[0] && el.parentElement.children[0].focus();
                } else if (e.key === "End") {
                    el.parentElement.children[this.aCheckCodeInput.length - 1] &&
                    el.parentElement.children[this.aCheckCodeInput.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();
                }
            },
			// 输入验证码,解决一个输入框输入多个字符的问题
            fnCheckCodeInputEvent(e) {
                let index = e.target.dataset.index * 1;
                let el = e.target;
                el.value = el.value
                    .replace(/Digit|Numpad/i, "")
                    .slice(0, 1);
                this.aCheckCodeInput[index] = el.value;
            },
            // 验证码粘贴
            fnCheckCodeKeyPaste(e) {
                e.clipboardData.items[0].getAsString((str) => {
                    if (str.toString().length === 6) {
                        this.aCheckCodePasteResult = str.split("");
                        document.activeElement.blur();
                        this.aCheckCodeInput = this.aCheckCodeInputComputed;
                        this.aCheckCodePasteResult = [];
                    } else {
                        // 如果粘贴内容不合规,清除所有内容
                        this.aCheckCodeInput = ['','','','','',''];
                    }
                });
            },
		}
	}
</script>
<style>
.g-remove-check-code {
    width: 100%;
    padding: 4px 0 8px 0;
}

.g-remove-check-code .g-remove-check-code_title {
    font-size: 14px;
    color: #666;
}

.g-remove-check-code .g-remove-check-code_content {
    display: flex;
    justify-content: space-between;
    align-items: center;
    width: 400px;
    padding: 28px 0 28px 0;
    margin: 0 auto;
}

.g-remove-check-code .g-remove-check-code_content input {
    width: 50px;
    height: 50px;
    font-size: 36px;
    text-align: center;
    border: none;
    outline: none;
    border: solid 1px rgba(187, 187, 187, 100);
    border-radius: 4px;
    -moz-appearance: textfield;
}

.g-remove-check-code .g-remove-check-code_content input.g-code-input_color {
    border-color: #5290FF;
}

.g-remove-check-code .g-remove-check-code_content input::-webkit-outer-spin-button,
.g-remove-check-code .g-remove-check-code_content input::-webkit-inner-spin-button {
    appearance: none;
    margin: 0;
}

.g-remove-check-code .g-remove-check-code_tip {
    font-size: 14px;
    color: #999;
    text-align: center;
}
</style>

增加功能

  • 按回车键提交验证码
	computed: {
		// 检测验证码是否输入完整
		bCheckCodeInputComplete() {
			return this.aCheckCodeInput.some(item => item === '');
		}
	},
	// 若输入Enter 返回;取消最后一个输入框的判断
	fnCheckCodeKeyup(e) {
		if(e.key === 'Enter') return;
        let index = e.target.dataset.index * 1;
            let el = e.target;
            // 解决输入e的问题
            el.value = el.value
                .replace(/Digit|Numpad/i, "")
                .slice(0, 1);
            if (/Digit|Numpad/i.test(e.code)) {
                // 必须在这里赋值,否则输入框会是空值
                this.aCheckCodeInput.splice(index, 1, e.code.replace(/Digit|Numpad/i, ""));
                el.nextElementSibling && el.nextElementSibling.focus();
         }
	},
	// 增加回车键判断
	fnCheckCodeKeydown(e) {
		let index = e.target.dataset.index * 1;
          let el = e.target;
          // 按 Enter 回车键,提交表单
          if(e.key === 'Enter') {
              if(this.bCheckCodeInputComplete) {
                  this.$message.warning('请输入六位数验证码~');
                  return;
              }
              // 执行请求接口方法
              return;
         }
         ...
	}

参考链接

https://zhuanlan.zhihu.com/p/152145625


  • 8
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

忍冬 ⁡⁡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值