vue3发送验证码倒计时 (防止连点、封装复用)

news2024/11/30 6:53:09

一、实现思路

倒计时 流程图

二、实现一个简单的验证码倒计时

//倒计时初始变量
const codeNum = ref(60);
// 定时器id
let clearId: number;
// 发送验证码
const sendCode = async () => {
// 防止下次点击 如果倒计时的时间不是60 就不执行下面逻辑
  if (codeNum.value != 60) return;
  // 掉接口
  const res = await getCode(mobile.value, "login");
// 把定时器赋值给 变量clearId 目的:清除定时器
  clearId= setInterval(() => {
    // 每次 时间1s -1
    codeNum.value--;
    // 时间=0时 清除定时器 
    if (codeNum.value == 0) {
      clearInterval(clearId);
    // 还原 倒计时60s
      codeNum.value = 60;
    }
  }, 1000);
};

当然 这只是没有做过优化的一个发送验证码,如果要考虑点击连续点击或者离开页面时销毁定时器 还要加一些功能

三、优化 

(1)第一种方案,定义一个变量来控制 如果之前没有点击 再次点击不再执行

<script lang="ts" setup>
// 接口
import { getCode } from "@/api/login";
// 定时器id
let clearId:number;
// 倒计时时间
const codeNum = ref(60);
// 手机号
const mobile = ref("13230000001");
// 是否发送了验证码 防止连点
+ const isClickSend = ref(false);

// 发送验证码
const sendCode = async () => {
+ if (isClickSend.value || codeNum.value != 60) return;
  isClickSend.value = true;
  const res = await getCode(mobile.value, "login");
  clearId.value = setInterval(() => {
    codeNum.value--;
    if (codeNum.value == 0) {
      clearInterval(clearId.value);
      codeNum.value = 60;
+      isClickSend.value = false;
    }
  }, 1000);
  console.log("sendCode", res);
};

</script>

<template>
     <a
    href="javascript:;"
    @click="sendCode"
   >{{ codeNum == 60 ? "发送验证码" : `(${codeNum})发送验证码` }}</a>
</template>

(2)第二种方案. 让倒计时初始值为0 调用函数时在赋值为60 下次值大于0时同样不再执行,实现思路和第一种相似

const codeNum = ref(0);

const sendCode = async () => {
  if (codeNum.value > 0) return;
  isClickSend.value = true;
  const res = await getCode(mobile.value, "login");
  codeNum.value = 60 
  if(clearId) clearInterval(clearId)
  clearId = setInterval(() => {
    codeNum.value--;
    if (codeNum.value == 0) {
      clearInterval(clearId);
    }
  }, 1000);
};

其中没有对手机号进行校验 若需要则自己可以写校验规则,也可以参考当前使用的其他组件库使用 

离开页面销毁定时器

 onMounted(() => {
        clearInterval(clearId)
 })

四、逻辑封装

为什么要封装 验证码倒计时功能?

1. 为了下次再次使用时 直接copy代码达到复用

2. 在日常开发中可能 有很多场景都需要发送验证码 只是 接口一样 只是参数的type值不一样 例如 登录需要传login  注册需要传register 到时候只需要调用更换参数即可

新建composable/index.ts 准备放公共方法

// 引用 发送的验证码类型
import type { CodeType } from '@/type/user'
// 引入接口
import { getCode } from "@/api/login";
import type { Ref } from 'vue'
// 引入vant form类型 用来初始化form类型 可参考vant 若没有使用 则删除
import type { FormProps, FormInstance } from 'vant';

// 封装方法   只需要传入手机号、 type类型
export const useSendCode = (mobile:  Ref<string>, type: CodeType) => {
    // 定义定时器初始值为0
    const timer = ref(0)
    // 定义form变量 如果用了vant 记得要给vanForm 绑定ref
    const form =  ref<FormInstance | null>() ;
    // 定义定时器id 为了清除定时器
    let timerId: number
    // 之后页面调用send方法来使用 
    const send = async () => {
        // 第二次点击 大于0时 直接 return
        if (timer.value > 0) return
        // 校验 mobile字段 要和 van-field 中的name保持一直 否则校验失败 如果校验失败则不走下面代码  注意await
        await form.value?.validate('mobile')
        // 校验通过调用接口
        await getCode(mobile.value, type)
        // 赋值倒计时  可修改成自己需要的时间
        timer.value = 10
        // 如果之前id存在可清除
        if (timerId) clearInterval(timerId)
        // 赋值定时器id
        timerId = setInterval(() => {
            // 时间-1
            timer.value--
            // 倒计时结束 清除定时器
            if (timer.value == 0)  clearInterval(timerId)
            
        }, 1000)
    }
    // 
    onMounted(() => {
        clearInterval(timerId)
    })
    return { timer, send, form }
}

 由于代码中使用了插件 没有引入ref onMounted  需要可自行引入

页面中使用

<script lang="ts" setup>
    import { mobileRule } from "@/utils/rule";
    import { useSendCode } from "@/composable";
    const { send, timer, form } = useSendCode(mobile, "login");
</script> 

<template>
   <van-form ref="form" @submit="pwdLogin">
        <van-field
          v-model="mobile"
          name="mobile"
          maxlength="11"
          placeholder="请输入手机号"
          :rules="mobileRule"
        />
  </van-form>
 ...
  <a href="javascript:;" @click="sendCode" >
     {{ timer == 0 ? "发送验证码" : `(${timer})后发送验证码` }}
  </a> 
</template>

补充 mobileRule

import type { FieldRule } from 'vant'

const mobileRules: FieldRule[] = [
  { required: true, message: '请输入手机号' },
  { pattern: /^1[3-9]\d{9}$/, message: '手机号格式不正确' }
]

const passwordRules: FieldRule[] = [
  { required: true, message: '请输入密码' },
  { pattern: /^\w{8,24}$/, message: '密码需8-24个字符' }
]

const codeRules: FieldRule[] = [
  { required: true, message: '请输入验证码' },
  { pattern: /^\d{6}$/, message: '验证码为6位数字' }
]

export { mobileRules, passwordRules, codeRules }

 

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

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

相关文章

AcWing算法学习第三节---高精度问题.

系列文章目录 第一节快速排序 第二节二分法 学习路上的风景&#xff0c;我陪你一起去看&#xff0c;编程路上的算法&#xff0c;我陪你一起去学&#xff0c;朋友们你们好&#xff0c;我是夏目浅石&#xff0c;蟹蟹你点开文章和我一同进步&#xff0c;加油&#xff01;遇见更好…

2022Q3手机配件增长榜:手机壳、数据线等供求不断增加

本篇我们将继续来分析22年Q3季度中手机通讯行业的高增长概念。在手机通讯行业中&#xff0c;我们发现了3个高增长品类&#xff0c;分别是&#xff1a;手机耳机、手机壳、数据线。 一、手机配件类高增长概念——手机耳机 手机耳机可以分为不同种类&#xff0c;如&#xff1a;开放…

现代物流有哪些特点?

现代物流的特点有系统化、网络化、信息化、专用化和准时性和柔性化。 现代物流特点一&#xff1a;系统化 现代物流强调了物流体系是一个具有综合性和系统性的过程&#xff0c;以优化物流管理体系为目标&#xff0c;降低物流运营管理成本&#xff0c;实现企业效益提升&#xff0…

python笔记76-types.FunctionType 动态创建函数

前言 types.FunctionType 创建函数有2种方式&#xff1a; 从已有函数的基础上&#xff0c;创建一个新函数从一个compile 构建的函数对象上&#xff0c;创建一个新函数 FunctionType 使用 FunctionType 可以用于判断一个对象是不是函数 from types import FunctionType, Me…

中国互联网综合实力100强:猿辅导第39

11月2日&#xff0c;中国互联网企业综合实力指数发布会暨百家企业高峰论坛在厦门成功举办。发布会上&#xff0c;中国互联网协会正式发布了《中国互联网企业综合实力指数&#xff08;2022&#xff09;》以及2022年中国互联网综合实力前百家企业榜单。 北京猿力教育科技有限公司…

腾讯基础面

传送门1. 有了解过C吗&#xff1f;接受转语言吗&#xff1f;2. 有没有了解过一些框架的底层原理、底层优化、数据库的索引优化3. 了解过哪些Map&#xff0c;可以从底层简单说下嘛&#xff1f;4. 你项目中是如何去实现幂等性的&#xff1f;5. RPC的协议讲一讲&#xff0c;怎么处…

开源共建 | TIS整合数据同步工具ChunJun,携手完善开源生态

TIS整合ChunJun实操 B站视频&#xff1a; https://www.bilibili.com/video/BV1QM411z7w5/?spm_id_from333.999.0.0 一、ChunJun 概述 ChunJun是一款易用、稳定、高效的批流统一的数据集成框架&#xff0c;可基于实时计算引擎Flink实现多种异构数据源之间的数据同步与计算&…

MySQL日志管理、备份与恢复

文章目录一、mysql常用日志1、概述①、错误日志②、二进制日志③、中继日志④、慢查询日志⑤、通用查询日志&#xff0c;用来记录MySQL的所有连接和语句&#xff0c;默认是关闭的2、数据库中查询日志状态①、查看二进制日志开启状态②、查看慢查询日志功能是否开启③、查看慢查…

FPGA书籍

1、Xilinx FPGA 权威设计指南 本书系统地介绍了Xilinx新一代集成开发环境Vivado 2018的设计方法、设计流程和具体实现。 全书共11章&#xff0c;内容包括Xilinx新一代UltraScale结构、Vivado集成设计环境导论、Vivado工程模式基本设计实现、Vivado非工程模式基本设计实现、创建…

Java-1129

Java8 新特性 速度更快代码更少&#xff08;lambda、stream&#xff09;强大的Stream API便于并行最大化减少空指针异常Optional 速度更快&#xff1a;对底层数据结构哈希map的优化 解释说明hashmap基本原理 hashmap本质是一个长度16的数组元素的键值对以key&#xff1a;valu…

强化学习实战——Motion Imitation环境配置+所遇问题(win10)

GitHub代码 注意&#xff1a;本篇环境配置是基于上一篇强化学习实战——OpenAI Gym环境配置实战演示&#xff08;win10&#xff09;环境的延续&#xff01;&#xff01;&#xff01; 一、环境配置 1&#xff09;下载requirements.txt内安装包 问题1&#xff1a;pybullet不能…

天图资本通过香港上市聆讯:上半年利润下滑24%,王永华为董事长

11月29日&#xff0c;深圳市天图投资管理股份有限公司&#xff08;下称“天图投资”&#xff09;通过港交所聆讯并在港交所递交了聆讯后资料集&#xff08;即招股书&#xff09;。相较于此前招股书&#xff0c;天图资本补充了截至2022年6月30日的财务数据等信息。 招股书显示&a…

哪个牌子蓝牙耳机打电话清晰?通话最清晰的蓝牙耳机推荐

随着蓝牙耳机的普及&#xff0c;越来越多的数码产品如笔记本、平板等都要配有蓝牙耳机&#xff0c;因此&#xff0c;市场对于大电视、多用途、高性能的无线蓝牙耳机的需求不断扩张。蓝牙耳机再这几年不但才音质上采用了最新的技术&#xff0c;通话方面也有改进&#xff0c;下面…

测试开发之路,我在大厂做测试这四年的感悟

开篇 当开始写这篇文章时候&#xff0c;才感受到人生如白驹过隙&#xff0c;4 年时间飞逝&#xff0c;自己也从一个初入职场小白到能肩负项目核心事务的测试开发。在这里&#xff0c;总结 4 年来的心智成长之路&#xff0c;也是借机互相交流&#xff0c;并无对错之争&#xff…

Java web 项目Tamcat在IDEA控制台输出乱码

遇到乱码问题怎么解决呢&#xff1f; 出现乱码其实就是编码格式有问题&#xff0c;设置一下呗&#xff0c;我们先查看一下编码格式&#xff0c;在改一下 1.查看编码格式 首选进入Tamcat安装的根目录 进入conf目录 找到logging.prooperties文件并打开 查看编码格式 编码格式为…

单机服务器docker搭建mysql5.7主从同步

1.首先使用docker安装mysql5.7 docker pull mysql:5.7 2.创建主库&#xff08;从3306映射一个3308端口&#xff09; docker run -d -p 3308:3306 -v /home/mysql-master/conf:/etc/mysql/conf.d -v /home/mysql-master/data:/var/lib/mysql -v /home/mysql-master/log:/var/lo…

启程,2022亚马逊云科技re:Invent Peter带来主题演讲

北京时间11月29日&#xff0c;2022亚马逊云科技re:Invent全球大会开幕首日&#xff0c;亚马逊云科技高级副总裁Peter DeSantis带来最新创新产品隆重登场&#xff0c;其间不乏计算、网络、算法及Serverless等最新功能特性。 网络协议创新&#xff1a;新产品 新理念 基于亚马逊…

MCUXpresso IDE下高度灵活的FreeMarker链接文件模板机制

一、准备工作 首先需要准备好环境&#xff0c;包含必要的软件&#xff0c;痞子衡的环境如下&#xff1a; 集成开发环境&#xff1a; MCUXpresso IDE_11.6.0_8187&#xff0c;点此下载软件开发包&#xff1a; SDK_2.12.1_EVK-MIMXRT1170&#xff08;Toolchain需包含MCUXpresso I…

这么卷,现在测试工程师要求会写工具了?

Fintech概念正受到不少互联网金融公司的热捧&#xff0c;主要是指代那些可用于撕裂传统金融服务方式的高新技术。越来越多的企业开辟了新的部门去研究各种各样能让自己产品增值的科技类产品。 尤其是在很多互联网金融公司&#xff0c;业务分析师BA(Business Analyst)&#xff…

【Linux】-- 初识操作系统

目录 一、冯诺依曼体系结构 二、操作系统 1.概念 2.为什么要有操作系统 三.操作系统 1.硬件层 2.驱动层 3.操作系统层 4.用户层 &#xff08;1&#xff09;用户层 &#xff08;2&#xff09;系统调用接口 &#xff08;3&#xff09;用户操作接口 四、如何管理 1…