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

实现代码

可以随意填写删除 

<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.mfbz.cn/a/55676.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vscode里安装Go插件和配置Go环境

vscode是一款跨平台、轻量级、插件多的开源IDE&#xff0c;在vscode不仅可以配置C/C、Python、R、Ruby等语言的环境&#xff0c;还可以配置Go语言的环境。这里介绍在vscode里安装Go语言的插件和配置Go语言环境&#xff0c;系统是Win10 64位。 1、下载Go安装包和配置GOROOT、GO…

P3374 【模板】树状数组 1 浅谈树状数组 (内附封面)

【模板】树状数组 1 题目描述 如题&#xff0c;已知一个数列&#xff0c;你需要进行下面两种操作&#xff1a; 将某一个数加上 x x x 求出某区间每一个数的和 输入格式 第一行包含两个正整数 n , m n,m n,m&#xff0c;分别表示该数列数字的个数和操作的总个数。 第二…

【docker】Windows11系统下安装并配置阿里云镜像加速

【docker】Windows11系统下安装并配置阿里云镜像加速 提示:博主取舍了很多大佬的博文并亲测有效,分享笔记邀大家共同学习讨论 文章目录 【docker】Windows11系统下安装并配置阿里云镜像加速一、查看Windows环境是否支持docker二、 启动Hyper-V三、 官网下载安装Docker应用和数据…

数据包在网络中传输的过程

ref: 【先把这个视频看完了】&#xff1a;数据包的传输过程【网络常识10】_哔哩哔哩_bilibili 常识都看看 》Ref&#xff1a; 1. 这个写的嘎嘎好&#xff0c;解释了为啥4层7层5层&#xff0c;还有数据包封装的问题:数据包在网络中的传输过程详解_数据包传输_张孟浩_jay的博客…

python与深度学习(十三):CNN和IKUN模型

目录 1. 说明2. IKUN模型2.1 导入相关库2.2 建立模型2.3 模型编译2.4 数据生成器2.5 模型训练2.6 模型保存2.7 模型训练结果的可视化 3. IKUN的CNN模型可视化结果图4. 完整代码 1. 说明 本篇文章是CNN的另外一个例子&#xff0c;IKUN模型&#xff0c;是自制数据集的例子。之前…

VLAN介绍

目录 VLAN的特点: VLAN的好处: VLAN的实现原理 VLAN标签 VLAN的划分方式 接口划分VLAN--接口类型 Access接口 Trunk接口 Hybrid接口 实现VLAN之间通信 使用路由器物理接口 使用子接口 使用三层交换机的VLANIF接口 配置 VLANIF的转发流程 三层交换机参与下的三层…

洞悉安全现状,建设网络安全防护新体系

一、“网络攻防演练行动“介绍 国家在2016年发布《网络安全法》&#xff0c;出台网络安全攻防演练相关规定&#xff1a;关键信息基础设施的运营者应“制定网络安全事件应急预案&#xff0c;并定期进行演练”。同年“实战化网络攻防演练行动”成为惯例。由公安部牵头&#xff0…

STM32入门——GPIO输入输出

GPIO简介 GPIO&#xff08;General Purpose Input Output&#xff09;通用输入输出口 可配置为8种输入输出模式引脚电平&#xff1a;0V~3.3V&#xff0c;部分引脚可容忍5V输出模式下可控制端口输出高低电平&#xff0c;用以驱动LED、控制蜂鸣器、模拟通信协议输出时序等输入模…

前端开发:基于cypress的自动化实践

如何在vue中使用cypress如何运行cypress如何编写测试用例如何解决测试数据的问题遇到的元素定位的问题如何看待cypresscypress是否为最佳工具测试怎么办&#xff1f; 如何在vue中使用cypress vue提供了vue-cli 可以快速的创建vue项目。 vue create hello-world在选择安装项里…

JavaSE【继承、初始化、pretected封装、组合】

一、继承 继承 (inheritance) 机制 &#xff1a;是面向对象程序设计使代码可以复用的最重要的手段&#xff0c;它允许程序员在保持原有类特 性 的基础上进行扩展&#xff0c;增加新功能 &#xff0c;这样产生新的类&#xff0c;称 派生类 。 继承呈现了面向对象程序设计的层次结…

修改cuda软链接(实操演示)

文章目录 1 找到已存在的CUDA软链接2 确认当前软链接真实路径3 删除现有软链接4 创建新的软链接5 验证新的软链接 要修改CUDA的软链接&#xff0c;需要找到已经存在的软链接并重新创建它指向新的目录。 1 找到已存在的CUDA软链接 首先&#xff0c;需要找到之前创建的CUDA软链…

Maven 打包项目后,接口识别中文乱码

背景 项目在Idea里面运行&#xff0c;调用接口发送中文消息正常&#xff0c;用Maven打包项目后&#xff0c;运行jar包&#xff0c;调用接口发送中文出现乱码。 解决方法 1.Idea编译配置 2.如果更改了上述配置之后还是没有效果&#xff0c;则在运行jar包的前面加上 -Dfile.en…

windows自动化点击大麦app抢购、捡漏,仅支持windows11操作系统

文章目录 必要条件程序运行必要条件 确保windows11版本操作系统,如果不是可以通过镜像升级为windows11如果已经是windows11操作系统,确保更新到最新版本 修改系统所在时区,将国家或地区改为美国 开启虚拟化 勾选Hyper-V,如果没有则不需要勾选 勾选虚拟机平台 勾选完毕,点…

go 结构体 - 值类型、引用类型 - 结构体转json类型 - 指针类型的种类 - 结构体方法 - 继承 - 多态(interface接口) - 练习

目录 一、结构体 1、python 与 go面向对象的实现&#xff1a; 2、初用GO中的结构体&#xff1a;&#xff08;实例化一个值类型的数据&#xff08;结构体&#xff09;&#xff09; 输出结果不同的三种方式 3、实例化一个引用类型的数据&#xff08;结构体&#xff09; 4、…

时序数据库 TDengine 与 WhaleStudio 完成相互兼容性测试认证

近年来&#xff0c;开源及其价值获得社会各界的广泛认可&#xff0c;无论是国家政策导向还是企业数字化转型&#xff0c;都在加速拥抱开源。对于如操作系统、数据库等基础软件来说&#xff0c;开源更是成为驱动技术创新的有力途径。 在此背景下&#xff0c;近日&#xff0c;涛…

Spring boot开发实用篇

一、热部署 1.启动热部署 1.导入坐标 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId> </dependency> 2.使用构建项目操作启动热部署 3.关于热部署 重启&#xff1a;自定义开发…

2023软考下半年考试和报名时间汇总(附详细报名流程)

2023年上半年软考结束了&#xff0c;相信有不少准备报考下半年软考的考生正摩拳擦掌&#xff0c;期待在11月的考试中大显身手。2023下半年软考什么时候报名呢&#xff1f;一起来看看吧~ 根据中国计算机技术职业资格网发布的关于《2023年度计算机技术与软件专业技术资格&#x…

完美解决PostgresSQL14或15安装后pgAdmin不能打开的问题(亲测有效)

今天安装PostgreSQL的时候遇到一个问题&#xff0c;由于选择的是安装时候自带的pgAdmin 后台如论如何都打不开&#xff0c;一直出现如下界面 一直在此界面&#xff0c;无法进入服务器。 通过修改.js配置&#xff0c;或者是删除C:\Users\PICC\AppData\Roaming\pgadmin目录下所…

SpringBoot复习:(12)SpringApplicationRunListener和 SpringApplicationRunListeners

SpringApplicationRunListener接口定义如下&#xff1a; public interface SpringApplicationRunListener {default void starting() {}default void environmentPrepared(ConfigurableEnvironment environment) {}default void contextPrepared(ConfigurableApplicationConte…
最新文章