Vue3实现6位验证码输入框,用户可以连续输入和删除

news2024/11/18 11:48:11

实现代码

可以随意填写删除 

<template>
  <div class="verification-container">
    <input
      v-for="(code, index) in verificationCodes"
      :key="index"
      v-model="verificationCodes[index]"
      @input="handleInput(index, $event)"
      @keydown="handleKeyDown(index, $event)"
      maxlength="1"
      class="verification-input"
    />
  </div>
</template>

<script>
import { ref, nextTick } from 'vue';

export default {
  setup() {
    const verificationCodes = ref(['', '', '', '', '', '']);

    const handleInput = (index, event) => {
      const value = event.target.value;
      verificationCodes.value[index] = value;

      // 自动跳到下一个输入框
      if (value && index < verificationCodes.value.length - 1) {
        const nextInput = event.target.nextElementSibling;
        if (nextInput) {
          nextTick(() => {
            nextInput.focus();
          });
        }
      }
    };

    const handleKeyDown = (index, event) => {
      // 处理删除操作
      if (event.key === 'Backspace' && !event.target.value && index > 0) {
        const prevInput = event.target.previousElementSibling;
        if (prevInput) {
          nextTick(() => {
            prevInput.focus();
          });
        }
      }
    };

    return {
      verificationCodes,
      handleInput,
      handleKeyDown
    };
  }
};
</script>

<style lang="scss" scoped>
.verification-container {
  display: flex;
}

.verification-input {
  width: 40px;
  height: 40px;
  margin-right: 10px;
  text-align: center;
  font-size: 18px;
  border: 1px solid #ccc;
  border-radius: 5px;
}

.verification-input:focus {
  outline: none;
  border-color: #007bff;
  box-shadow: 0 0 5px #007bff;
}
</style>

在更新后的代码中,我们添加了一个新的handleKeyDown方法来处理键盘按键事件。如果用户按下了 "Backspace" 键并且当前输入框为空,则将焦点设置到前一个输入框。

通过这个更改,当用户输入一半时,按下 "Backspace" 键会自动删除前一个输入框中的内容,并将焦点移动到前一个输入框,以允许用户重新输入。

请注意,我们使用了nextTick函数来确保在下一个DOM更新周期后设置焦点,以避免与Vue的响应式更新冲突。

希望这个更新后的代码能够解决问题,并允许用户在输入一半时删除前面的内容。

 

必须输入完整才能删除内容 

<template>
  <div class="verification-container">
    <input
      v-for="(code, index) in verificationCodes"
      :key="index"
      v-model="verificationCodes[index]"
      @input="handleInput(index, $event)"
      maxlength="1"
      class="verification-input"
    />
  </div>
</template>
<script>
import { ref } from 'vue';

export default {
  setup() {
    const verificationCodes = ref(['', '', '', '', '', '']);

    const handleInput = (index, event) => {
      const value = event.target.value;
      verificationCodes.value[index] = value;

      // 自动跳到下一个输入框
      if (value && index < verificationCodes.value.length - 1) {
        const nextInput = event.target.nextElementSibling;
        if (nextInput) {
          nextInput.focus();
        }
      }

      // 自动删除前面的内容
      if (!value && index > 0) {
        const prevInput = event.target.previousElementSibling;
        if (prevInput) {
          prevInput.focus();
        }
      }
    };

    return {
      verificationCodes,
      handleInput
    };
  }
};
</script>
<style lang="scss" scoped>
.verification-container {
  display: flex;
}

.verification-input {
  width: 40px;
  height: 40px;
  margin-right: 10px;
  text-align: center;
  font-size: 18px;
  border: 1px solid #ccc;
  border-radius: 5px;
}

.verification-input:focus {
  outline: none;
  border-color: #007bff;
  box-shadow: 0 0 5px #007bff;
}
</style>

使用v-for指令生成6个输入框,并将每个输入框的值绑定到verificationCodes数组中的对应索引位置。我们还使用@input事件监听输入框的输入,并调用handleInput方法处理输入事件。

在组件的逻辑部分,定义verificationCodes数组,并实现handleInput方法。

代码中,我们使用ref创建了一个名为verificationCodes的响应式数组,用于保存每个输入框的值。在handleInput方法中,我们更新对应索引位置的值,并根据输入的情况自动跳到下一个输入框或删除前面的内容。我们使用focus()方法将焦点设置到下一个或前一个输入框

残缺版代码

<template>
  <div class="custom-class">
    <!-- <input
        v-for="(item, index) in nums"
        :key="index"
        v-model="nums[index]"
        maxlength="1"
        :ref="`input${index}`"
        @keydown="onKeyDown(index, $event)"
        @input="handleInput(index)"
        @focus="onFocus(index)"
      /> -->
    <input
      v-model="nums[0]"
      maxlength="1"
      ref="input0"
      @keydown="onKeyDown(0, $event)"
      @input="handleInput(0)"
      @focus="onFocus(0)"
    />
    <input
      v-model="nums[1]"
      maxlength="1"
      ref="input1"
      @keydown="onKeyDown(1, $event)"
      @input="handleInput(1)"
      @focus="onFocus(1)"
    />
    <input
      v-model="nums[2]"
      maxlength="1"
      ref="input2"
      @keydown="onKeyDown(2, $event)"
      @input="handleInput(2)"
      @focus="onFocus(2)"
    />
    <input
      v-model="nums[3]"
      maxlength="1"
      ref="input3"
      @keydown="onKeyDown(3, $event)"
      @input="handleInput(3)"
      @focus="onFocus(3)"
    />
    <input
      v-model="nums[4]"
      maxlength="1"
      ref="input4"
      @keydown="onKeyDown(4, $event)"
      @input="handleInput(4)"
      @focus="onFocus(4)"
    />
    <input
      v-model="nums[5]"
      maxlength="1"
      ref="input5"
      @keydown="onKeyDown(5, $event)"
      @input="handleInput(5)"
      @focus="onFocus(5)"
    />
  </div>
</template>

<script setup>
import {
  defineProps,
  getCurrentInstance,
  reactive,
  ref,
  nextTick,
  watch,
  computed,
} from "vue";
const internalInstance = getCurrentInstance();

defineProps({
  isShowSecuityDia: Boolean,
});

let nums = reactive(["", "", "", "", "", ""]);
// const currentInput = ref(0);
// const input0 = ref(null);
// const input1 = ref(null);
// const input2 = ref(null);
// const input3 = ref(null);
// const input4 = ref(null);
// const input5 = ref(null);

// nextTick(() => {
//   // input0.value.focus();
//   currentInput.value++;
//   // console.log(["input" + currentInput.value].value, "123");
//   // console.log(input0.value.value);
// });

// watch(
//   nums,
//   () => {
//     console.log(currentInput.value, 888);
//     if (currentInput.value === 1) {
//       currentInput.value += 1;
//       input1.value.focus();
//     } else if (currentInput.value === 2) {
//       currentInput.value += 1;
//       input2.value.focus();
//     } else if (currentInput.value === 3) {
//       currentInput.value += 1;
//       input3.value.focus();
//     } else if (currentInput.value === 4) {
//       currentInput.value += 1;
//       input4.value.focus();
//     } else if (currentInput.value === 5) {
//       currentInput.value += 1;
//       input5.value.focus();
//     }
//   },
//   { deep: true }
// );

// const emits = defineEmits(["changeRemDialog"]);
// const confirmSubmit = () => {
//   let code = nums.join("");
//   nums = reactive(["", "", "", "", "", ""]);
//   emits("changeRemDialog", code);
// };

let activeIndex = 0;

const onKeyDown = (index, e) => {
  // console.log(index, e, activeIndex, 888);
  switch (e.keyCode) {
    case 8: // backspace键
      e.preventDefault();
      if (nums[index]) {
        nums[index] = "";
        if (index > 0) {
          activeIndex = index - 1;
          const prevInput = internalInstance.ctx.$refs[`input${index - 1}`];
          prevInput.focus();
        }
      } else if (index === 0) {
        activeIndex = 0;
      }
      break;
    default:
      break;
  }
};

const handleInput = (index) => {
  // console.log(index, activeIndex, 999);
  if (nums[index]) {
    activeIndex = index;
    if (index < 5) {
      const nextInput = internalInstance.ctx.$refs[`input${index + 1}`];
      nextInput.focus();
    }
  }
};

const onFocus = (index) => {
  activeIndex = index;
};

// const deleteLastNum = () => {
//   if (currentInput.value === 6) {
//     input5.value.focus();
//     currentInput.value + -1;
//   } else if (currentInput.value === 5) {
//     input4.value.focus();
//     currentInput.value + -1;
//   }
// };

// 把六个数字拼接成一个变量
const code = computed(() => {
  return nums.join("");
});
// console.log(code);
</script>
<style lang="scss" scoped>
.custom-class {
  display: flex;
  justify-content: space-between;
  align-items: center;
  input {
    width: 75px;
    height: 75px;
    background: #ffffff;
    border: 1px solid #d9d9d9;
    border-radius: 12px;
    font-size: 40px;
    // caret-color: rgba(0, 0, 0, 0);
  }
}
</style>

 以下是一个简单的 Vue3 组件来实现6位验证码输入框的功能,其中用户可以连续输入和删除。

<template>
  <div class="verification-code">
    <input
      v-for="(item, index) in codeList"
      :key="index"
      :ref="`codeInput${index}`"
      v-model.trim="codeList[index]"
      :class="{ 'code-active': activeIndex === index }"
      @keydown="onKeyDown(index, $event)"
      @input="onInput(index)"
      @focus="onFocus(index)"
    />
  </div>
</template>

<script>
import { defineComponent } from 'vue';

export default defineComponent({
  name: 'VerificationCode',
  setup(props, { emit }) {
    const codeList = Array(6)
      .fill('')
      .map((item) => item);

    let activeIndex = 0;

    const onKeyDown = (index, e) => {
      switch (e.keyCode) {
        case 8: // backspace键
          e.preventDefault();
          if (codeList[index]) {
            codeList[index] = '';
            if (index > 0) {
              activeIndex = index - 1;
              const prevInput = $refs[`codeInput${index - 1}`];
              prevInput.focus();
            }
          } else if (index === 0) {
            activeIndex = 0;
          }
          break;
        default:
          break;
      }
    };

    const onInput = (index) => {
      if (codeList[index]) {
        activeIndex = index + 1;
        if (activeIndex < 6) {
          const nextInput = $refs[`codeInput${activeIndex}`];
          nextInput.focus();
        }
      }
    };

    const onFocus = (index) => {
      activeIndex = index;
    };

    return {
      codeList,
      activeIndex,
      onKeyDown,
      onInput,
      onFocus
    };
  }
});
</script>

<style scoped>
.verification-code {
  display: flex;
  justify-content: center;
  align-items: center;
}

input {
  width: 4em;
  height: 4em;
  margin: 0 0.5em;
  font-size: 2em;
  text-align: center;
  border: 1px solid #ccc;
  border-radius: 5px;
}

input:focus {
  outline: none;
}

.code-active {
  border-color: #007fff;
}
</style>

使用该组件的示例:

<template>
  <div class="app">
    <verification-code />
  </div>
</template>

<script>
import VerificationCode from './components/VerificationCode.vue';

export default {
  name: 'App',
  components: {
    VerificationCode
  }
};
</script>

<style>
.app {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
}
</style>

这个组件中,我们使用了 Arrayfill 方法,来创建一个长度为6、每个元素都为空字符串的数组 codeList。然后,我们使用 v-for 循环这个数组,为每个元素创建一个输入框,并为其绑定 v-model 实现双向数据绑定。我们还绑定了 @keydown 事件来监听用户按键操作,以及 @input@focus 事件来监听输入和焦点变化。

onKeyDown 函数中,我们首先判断是否按下的是 backspace 键,如果是,我们会阻止默认行为,然后检查当前输入框是否为空字符串。如果不为空,我们会将其置为空字符串,然后检查当前输入框的索引是否大于0。如果是,我们会将 activeIndex 设置为当前输入框的索引减一,并将光标移动到前一个输入框。如果当前输入框的索引已经是0,我们会将 activeIndex 设置为0,以确保用户可以从第一个输入框开始删除验证码。

onInput 函数中,我们先检查当前输入框是否已经输入了值。如果是,我们会将 activeIndex 设置为当前输入框的索引加一,并将光标移到下一个输入框。

onFocus 函数中,我们将 activeIndex 设置为当前输入框的索引,以确保用户可以通过 tab 键和鼠标点击等操作来移动光标。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/826653.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux系统控制文件和目录权限

0.前言 并非操作系统的每个用户都应具有相同级别的文件和目录访问权限&#xff0c;与任何专业操作系统一样&#xff0c;Linux具有保护文件和目录访问的方法。系统允许系统管理员(root用户或文件所属用户)通过赋予用户读取&#xff0c;写入或执行文件的权限来保护其文件免受不必…

生成对抗网络DCGAN学习

在AI内容生成领域&#xff0c;有三种常见的AI模型技术&#xff1a;GAN、VAE、Diffusion。其中&#xff0c;Diffusion是较新的技术&#xff0c;相关资料较为稀缺。VAE通常更多用于压缩任务&#xff0c;而GAN由于其问世较早&#xff0c;相关的开源项目和科普文章也更加全面&#…

如何在 Ubuntu 上部署 ONLYOFFICE 协作空间社区版?

ONLYOFFICE 协作空间是一个在线协作平台&#xff0c;帮助您更好地与客户、业务合作伙伴、承包商及第三方进行文档协作。今天我们来介绍一下&#xff0c;如何在 Ubuntu 上安装协作空间的自托管版。 ONLYOFFICE 协作空间主要功能 使用 ONLYOFFICE 协作空间&#xff0c;您可以&am…

Golang 函数参数的传递方式 值传递,引用传递

基本介绍 我们在讲解函数注意事项和使用细节时&#xff0c;已经讲过值类型和引用类型了&#xff0c;这里我们再系统总结一下&#xff0c;因为这是重难点&#xff0c;值类型参数默认就是值传递&#xff0c;而引用类型参数默认就是引用传递。 两种传递方式&#xff08;函数默认都…

MySQL数据库备份

目录 一、概述 二、数据备份的重要性 三、造成数据丢失的原因 四、备份类型 五、常见的备份方法 六、备份 一、概述 数据库备份是指将数据库中的数据、表格、视图、存储过程、触发器等信息备份到另一个地方&#xff0c;以便在数据库丢失或损坏时进行恢复。数据库备份是数…

以CS32F031为例浅说国产32位MCU的内核处理器

芯片内核又称CPU内核&#xff0c;它是CPU中间的核心芯片&#xff0c;是CPU最重要的组成部分。由单晶硅制成&#xff0c;CPU所有的计算、接受/存储命令、处理数据都由核心执行。各种CPU核心都具有固定的逻辑结构&#xff0c;一级缓存、二级缓存、执行单元、指令级单元和总线接口…

【C++】string类

目录 &#x1f31e;专栏导读 &#x1f31b;为什么学习string类&#xff1f; ⭐C语言中的字符串 &#x1f31b;标准库中的string类 ⭐基本使用string ⭐string类的常用接口 ⭐总结&#xff1a; &#x1f31b;范围for的使用 &#x1f31e;专栏导读 &#x1f31f;作者简介…

docker更换数据存储路径

1. 先停掉docker服务 sudo systemctl stop docker 可能会出现的问题&#xff1a; 这样会导致docker关闭失败,解决办法&#xff1a;systemctl stop docker.socket 确保docker关闭: 2.备份现在的 Docker 数据存储目录 /var/lib/docker(默认路径) mv /var/lib/docker /var/lib/…

高斯函数的傅里叶变换与离散化频谱分析

1 高斯函数的傅里叶变换 主要参考自 http://www.cse.yorku.ca/~kosta/CompVis_Notes/fourier_transform_Gaussian.pdf 对于中心化的高斯函数&#xff0c;即 g ( x ) 1 2 π σ e − x 2 2 σ 2 , (1.1) g\left( x \right) \frac{1}{{\sqrt {2\pi } \sigma }}{e^{ - \frac{{{x…

【有趣的】关于Map的一些小测试

Map在代码中用到得非常多&#xff0c;它是无序的、key-value结构的&#xff0c;其读取会非常快。 今天看了个小文章Map判空 、空字符串、空key值等各种判断方法&#xff0c;你都掌握了吗&#xff1f;便自己也玩一下。 一、判空 因为对象已经new出来了&#xff0c;所以map指向的…

【洁洁送书第三期】人性的光辉,python之光

这里写目录标题 python学习现状python之光亮点python学习配套视频python之光目录强力推荐 python学习现状 作为生产力工具&#xff0c;Python是当今极为流行的编程语言。Python编程逐渐成为一项通用能力&#xff0c;从小学生到各个行业的从业人员都在学Python。Python确实能够…

高忆管理:多重利好共振 外资加码布局A股

资本商场活泼信号正在继续开释&#xff0c;内外资决心取得有力提振。以北向资金为代表的外资近来表现活泼&#xff0c;近六个买卖日已连续净买入超500亿元。多家外资组织近期表态称&#xff0c;伴跟着方针力度加强&#xff0c;我国经济有望继续复苏&#xff0c;活泼看好我国权益…

优思学院|质量工程师应具备什么能力?

质量工程师是一个需要耐心、细心、坚持态度、沟通能力、协调能力的工作&#xff0c;更需要持续学习强化自身的专业知识。 质量工程师负责审核、客户投诉的调查、过程的改进以达到质量之提升&#xff0c;他們也必须要预警生产线风险、质量异常&#xff0c;并且协调不同的部門一…

【雕爷学编程】Arduino动手做(181)---Maixduino AI开发板2

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

[语义分割] ASPP不同版本对比(DeepLab、DeepLab v1、DeepLab v2、DeepLab v3、DeepLab v3+、LR-ASPP)

1. 引言 1.1 本文目的 本文主要对前段时间学习的 ASPP 模块进行对比&#xff0c;涉及到的 ASPP 有&#xff1a; ASPP in DeepLab v2&#xff0c;简称 ASPP v2ASPP in DeepLab v3&#xff0c;简称 ASPP v3ASPP in DeepLab v3&#xff0c;简称 ASPP v3ASPP in MobileNet v3&am…

开发提测?

前言 开发提测是正式开始测试的重要关卡&#xff0c;提测质量的好坏会直接影响测试阶段的效率&#xff0c;进而影响项目进度。较好的提测质量&#xff0c;对提高测试效率和优化项目进度有着事半功倍的作用。如何更好的推进开发提高提测质量呢&#xff1f;下面小编结合自己项目…

攻防世界-web-lottery

题目描述&#xff1a;里面有个附件&#xff0c;是网站的源代码&#xff0c;还有一个链接&#xff0c;是线上的网站 主页告诉了我们规则&#xff1a; 1. 每个人的初始金额为20美元 2. 一支彩票2美元&#xff0c;挑选7个数字&#xff0c;根据匹配上的数字有不同的奖励 我们先体…

基于dynamorio自制反汇编小工具 instr_trace安装

目录 概述一、下载源码二、安装dynamorio1、安装依赖2、编译3、测试安装是否成功参考截图 三、安装instr_trace工具1、文件说明2、编译3、运行 四、生成的文件格式说明&#xff08;1&#xff09;mov指令&#xff08;寄存器->寄存器&#xff09;&#xff08;2&#xff09;mov…

用 Yara 对红队工具 “打标“

​前言: YARA 通常是帮助恶意软件研究人员识别和分类恶意软件样本的工具&#xff0c;它基于文本或二进制模式创建恶意样本的描述规则&#xff0c;每个规则由一组字符串和一个布尔表达式组成&#xff0c;这些表达式决定了它的逻辑。 但是这次我们尝试使用 YARA 作为一种扫描工…

ELK日志分析系统介绍及搭建(超详细)

目录 一、ELK日志分析系统简介 二、Elasticsearch介绍 2.1Elasticsearch概述 三、Logstash介绍 四、Kibana介绍 五、ELK工作原理 六、部署ELK日志分析系统 6.1ELK Elasticsearch 集群部署&#xff08;在Node1、Node2节点上操作&#xff09; 6.2部署 Elasticsearch 软件 …