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

 更新时间:2023年01月07日 11:25:44   作者:奥特曼  
这篇文章主要介绍了vue3发送验证码倒计时功能的实现(防止连点、封装复用),实现思路是点击发送验证码,验证码倒计时,校验手机号是否正常等一系列操作,本文通过示例代码介绍的非常详细,需要的朋友可以参考下

一、实现思路

倒计时 流程图

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

//倒计时初始变量
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:;" rel="external nofollow"  rel="external nofollow" 
    @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:;" rel="external nofollow"  rel="external nofollow"  @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 }

到此这篇关于vue3发送验证码倒计时 (防止连点、封装复用)的文章就介绍到这了,更多相关vue3验证码倒计时内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • vue中data数据之间如何赋值问题

    vue中data数据之间如何赋值问题

    这篇文章主要介绍了vue中data数据之间如何赋值问题,具有很好的参考价值,希望对大家有所帮助。
    2022-09-09
  • axios请求中以params或body形式传递参数的区别浅析

    axios请求中以params或body形式传递参数的区别浅析

    最近在做自己项目中,做一个非常简单的新增用户场景,但是使用原生axios发送post请求的时候,还是踩了不少坑的,下面这篇文章主要给大家介绍了关于axios请求中以params或body形式传递参数的区别的相关资料,需要的朋友可以参考下
    2023-04-04
  • 详解mpvue开发小程序小总结

    详解mpvue开发小程序小总结

    这篇文章主要介绍了详解mpvue开发小程序小总结,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-07-07
  • Vue pinia模块化全局注册详解

    Vue pinia模块化全局注册详解

    这篇文章主要介绍了Vue pinia模块化全局注册,Pinia是Vue.js团队成员专门为Vue开发的一个全新的状态管理库,并且已经被纳入官方github
    2023-02-02
  • vue中优雅实现数字递增特效的详细过程

    vue中优雅实现数字递增特效的详细过程

    项目中需要做数字滚动增加的效果,一开始很懵,研究了一下原理,发现很简单,下面这篇文章主要给大家介绍了关于vue中优雅实现数字递增特效的详细过程,需要的朋友可以参考下
    2022-12-12
  • Vue Router动态路由实现实现更灵活的页面交互

    Vue Router动态路由实现实现更灵活的页面交互

    Vue Router是Vue.js官方的路由管理器,用于构建SPA(单页应用程序),本文将深入探讨Vue Router的动态路由功能,希望可以帮助大家更好地理解和应用Vue.js框架
    2024-02-02
  • 详解如何运行vue项目

    详解如何运行vue项目

    这篇文章主要介绍了如何运行vue项目,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • 关于Vue.js一些问题和思考学习笔记(2)

    关于Vue.js一些问题和思考学习笔记(2)

    这篇文章主要为大家分享了关于Vue.js一些问题和思考的学习笔记,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-12-12
  • Vue CLI中模式与环境变量的深入详解

    Vue CLI中模式与环境变量的深入详解

    模式是 Vue CLI 项目中一个重要的概念,下面这篇文章主要给大家介绍了关于Vue CLI中模式与环境变量的相关资料,需要的朋友可以参考下
    2021-05-05
  • vue+tp5实现简单登录功能

    vue+tp5实现简单登录功能

    这篇文章主要为大家详细介绍了vue+tp5实现简单登录功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11

最新评论