当前位置: 首页 > article >正文

vue3实现输入框短信验证码功能---全网始祖

组件功能分析
1.按键删除,清空当前input,并跳转prevInput & 获取焦点,按键delete,清空当前input,并跳转nextInput & 获取焦点。按键Home/End键,焦点跳转first/最后一个input输入框。ArrowLeft/ArrowRight键点击后跳转上一个/下一个输入框获取焦点。
2.判断按键为数字,则取第一个数字,然后跳转下一个input输入框获取焦点,如果为最后一个,则失去焦点,交互结束。
3.粘贴功能。通过el.clipboardData获取粘贴内容,判断是否为4/6位粘贴内容。是则赋值给页面Input,双向绑定一个数组即可。否则置为空。

代码展示

<template>
	<div class="g-remove-check-code">
		<p class="g-remove-check-code_title">发送验证码</p>
		<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="text" 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="text" />
          <input :class="{'g-code-input_color': aCheckCodeInputComputed[2] !== ''}" max="9" min="0" maxlength="1" data-index="2" v-model.trim.number="aCheckCodeInputComputed[2]" type="text" />
          <input :class="{'g-code-input_color': aCheckCodeInputComputed[3] !== ''}" max="9" min="0" maxlength="1" data-index="3" v-model.trim.number="aCheckCodeInputComputed[3]" type="text" />
        </div>
      </div>
      <div class="btn-box">
        <button
          :disabled="!turnOff"
          content-text="下一步"
          @clickEvent="enter"
        />
      </div>
    </div>
</div>
</template>

<script lang="ts" setup>
import { defineComponent, ref, onMounted, onUnmounted, reactive, computed, getCurrentInstance, inject  } from "vue";
  let aCheckCodeInput = ref(["", "", "", ""]) 	// 存储输入验证码内容
  let aCheckCodePasteResult = ref([]) 	
 const turnOff = computed(() => {
    return aCheckCodeInputComputed.value.filter((v) => !!v)?.length >= 4;
  });
  onUnmounted(() => {
    clearInterval(timer.value);
  })

const enter = async () => {
    console.log("your code",aCheckCodeInputComputed.value.join("").toUpperCase())
  }
		const aCheckCodeInputComputed = computed(() => {
    if(aCheckCodePasteResult.value.length === 4) {
      return aCheckCodePasteResult.value;
    } else if (aCheckCodeInput.value && Array.isArray(aCheckCodeInput.value) && aCheckCodeInput.value.length === 4) {
      return aCheckCodeInput.value;
    } else if (/^\d{4}$/.test(aCheckCodeInput.value.toString())) {
      return aCheckCodeInput.value.toString().split("");
    } else {
      return new Array(4);
    }
  })

  // 输入验证码,更新验证码数据
  const fnCheckCodeKeyup = (e: any) => {
    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)) {
      // 必须在这里赋值,否则输入框会是空值
      aCheckCodeInput.value.splice(index, 1, e.code.replace(/Digit|Numpad/i, ""));
      el.nextElementSibling && el.nextElementSibling.focus();
      if (index === 3) {
        if (aCheckCodeInput.value.join("").length === 4)  (document.activeElement as any).blur();
      }
    }
  }

  // 输入验证码,检测位置变化
  const fnCheckCodeKeydown = (e: any) =>{
    let index = e?.target?.dataset?.index * 1;
    let el = e.target;
    if (e?.key === "Backspace") {
      if (aCheckCodeInput.value[index].length > 0) {
        aCheckCodeInput.value.splice(index, 1, "");
      } else {
        if (el.previousElementSibling) {
          el.previousElementSibling.focus();
          aCheckCodeInput.value[index - 1] = "";
        }
      }
    } else if(e?.key === "Delete") {
      if (aCheckCodeInput.value[index].length > 0) {
        aCheckCodeInput.value.splice(index, 1, "");
      } else {
        if(el.nextElementSibling) {
          el.nextElementSibling.focus();
          aCheckCodeInput.value[++index] = "";
        }
      }
    } else if (e?.key === "Home") {
      el?.parentElement?.children[0] && el.parentElement.children[0].focus();
    } else if (e?.key === "End") {
      el?.parentElement?.children[aCheckCodeInput.value.length - 1] &&
      el?.parentElement?.children[aCheckCodeInput.value.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 === 'Enter') {
         this.doActive()
     }
  }

  // 输入验证码,解决一个输入框输入多个字符的问题
  const fnCheckCodeInputEvent = (e: any) => {
    let index = e?.target?.dataset?.index * 1;
    let el = e?.target;
    el.value = el?.value
      .replace(/Digit|Numpad/i, "")
      .slice(0, 1);
    aCheckCodeInput.value[index] = el.value;
  }

  // 验证码粘贴
  const fnCheckCodeKeyPaste = (e: any) =>{
    e?.clipboardData?.items[0].getAsString((str: string) => {
      if (str.toString().length === 4) {
        aCheckCodePasteResult.value = str.split("") as any;
        (document.activeElement as any).blur();
        aCheckCodeInput.value = aCheckCodeInputComputed.value;
        aCheckCodePasteResult.value = [];
      } else {
        // 如果粘贴内容不合规,清除所有内容
        aCheckCodeInput.value = ["", "", "", ""];
      }
    });
  }
</script>
<style scoped lang="scss">
.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>

效果展示
在这里插入图片描述


http://www.kler.cn/a/274459.html

相关文章:

  • 【Apache Doris】周FAQ集锦:第 26 期
  • Kubernetes(K8s)学习笔记
  • Mac系统Android sdk的安装
  • 2024年12月CCF-GESP编程能力等级认证Python编程一级真题解析
  • 深入解析与防范:基于缓冲区溢出的FTP服务器攻击及调用计算器示例
  • 17.springcloud_openfeign之扩展组件一
  • 【华为OD机试】绘图机器【C卷|100分】
  • 虚拟游戏理财 - 华为OD统一考试(C卷)
  • CVE-2019-5782:kArgumentsLengthType 设置偏小导致优化阶段可以错误的去除 CheckBound 节点
  • 【ESP32 IDF】ESPTIMER定时器
  • Java八股文(RabbitMQ)
  • mysql事务和行锁
  • 串口123
  • 《算法王晓东》最小重量机器设计问题
  • JavaSE(上)-Day6
  • 基于openresty构建运维工具链实践
  • Elasticsearch常用语句
  • 系统架构设计师笔记第37期:数据访问层设计
  • 保姆级docker 容器安装部署 MySQL:5.7主从复制
  • 从零开始写 Docker(六)---实现 mydocker run -v 支持数据卷挂载
  • 搭建项目后台系统基础架构
  • 【MySQL】MySQL视图
  • c++ 递增的5位数
  • 15届蓝桥杯备赛(2)
  • 管道(acwing,蓝桥杯,二分)
  • P8717 [蓝桥杯 2020 省 AB2] 成绩分析 Python