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

目录
  • 一、实现思路
  • 二、实现一个简单的验证码倒计时
  • 三、优化
  • 四、逻辑封装
  • 补充 mobileRule

一、实现思路

倒计时 流程图

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

//倒计时初始变量
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验证码倒计时内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • vue实现web前端登录页数字验证码

    本文实例为大家分享了vue实现web前端登录页数字验证码的具体代码,供大家参考,具体内容如下 1.创建code.js文件夹下面是js代码 function GVerify(options) {     console.log(); // 创建一个图形验证码对象,接收options对象为参数     this.con = document.getElementById(options)     this.options = { // 默认options参数值         id: '', //

  • Vue3 实现验证码倒计时功能(刷新保持状态)

    目录 前言 代码实现 小结 前言 倒计时的运用场景是需要经常用到的,但是根据业务的不同,好比手机验证码或者是邮箱验证码之类的,即使用户跳转到其它页面或者刷新,再次回到登录也,验证码的倒计时也得保持状态,大家参考逻辑即可,每个人的项目不同,这里提供大概的实现代码. 代码实现 主要逻辑 const state = reactive({ labelPosition: 'top', formData: { phone: '', code: '', }, // 倒计时 countDownTime: 60,

  • node+vue前后端分离实现登录时使用图片验证码功能

    目录 后端代码 前端代码 获取验证码方法 登录验证方法 记录一下前端使用验证码登录的过程后端用的是node.js,关键模块是svg-captcha前端使用的是vue2最后的登录界面如下: 后端代码 先上代码,然后解释 const svgCaptcha = require('svg-captcha') exports.checkCode = (req, res) => { const img = svgCaptcha.create({ size: 4, ignoreChars: '0o1l', c

  • vue发送验证码计时器防止刷新实现详解

    目录 基本实现效果 防止刷新 基本实现效果 按钮: <t-button @click="handleSend" :disabled="disable">{{text}}</t-button> data: text: '发送验证码', time: 10, timer: null, disable: false 点击发送: handleSend() { this.disable = true this.text = this.time + 's后

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

    目录 一.实现思路 二.实现一个简单的验证码倒计时 三.优化 四.逻辑封装 补充 mobileRule 一.实现思路 倒计时 流程图 二.实现一个简单的验证码倒计时 //倒计时初始变量 const codeNum = ref(60); // 定时器id let clearId: number; // 发送验证码 const sendCode = async () => { // 防止下次点击 如果倒计时的时间不是60 就不执行下面逻辑 if (codeNum.value != 60) retur

  • Rxjava实现发送验证码倒计时功能

    本文为大家分享了使用Rxjava做一个发送验证码倒计时,供大家参考,具体内容如下 首先在gradle添加依赖: compile 'io.reactivex:rxandroid:1.2.1' compile 'io.reactivex:rxjava:1.1.6' xml布局: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.

  • iOS发送验证码倒计时应用

    app注册的时候,经常会遇到发送验证码的功能,当点击发送验证码的时候,那个button就开始了倒计时,当计时结束才可以重新发送,效果如下: 具体代码实现如下: - (IBAction)sendMes:(UIButton *)sender { __block int timeout = 10 ; //倒计时时间 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispat

  • react native中的聊天气泡及timer封装成的发送验证码倒计时

    其实,今天我想把我近期遇到的坑都总结一下: 1.goBack的跨页面跳转,又两种方法,一可以像兔哥那样修改navigation源码,二可以用navigationActions 2.父子组件的传值,一可以用callBack  二可以用pubsub发布订阅模式 三可以用manager事件监听(a页面要显示的内容 有两种形式,一是从manager主动接收,也就是说不需要点击什么的获取数据,而是时时监听manager里数据的变化,第二种a页面获取要显示内容的形式是 点击出发,获取) 3 需要说的还是na

  • JS短信验证码倒计时功能的实现(没有验证码,只有倒计时)

    1.功能描述 当用户想要获取验证码时,就点击 免费获取验证码 ,然后开始倒计时,倒计时期间按钮文字为剩余时间x秒,且不可按状态,倒计时结束后,按钮更改为点击重新发送. 2.分析 必须用到定时器.按钮点击后,在定时器内做出判断.倒计时60秒,到0结束. 3.代码实现: 重点介绍:定时器在进行下一次倒计时之前,一定要清除一下,这样的话保证下一次定时器倒计时是正常的. <!DOCTYPE html> <html> <head> <meta charset="U

  • jQuery实现的手机发送验证码倒计时效果代码分享

    这是一款基于jquery实现的手机发送验证码倒计时效果代码,可实现实时显示秒数倒计时的功能,还可实现对手机号码格式验证的功能,是一款常用的网站注册发送手机验证码特效代码. 效果描述: 注册一个网站,当需要发送验证码到手机上的时候,我们经常碰到这样的效果: 首先检测手机是否符合1开头,11位数字的格式: 若不符合,则提示错误信息并返回false: 否则提交给后台,后台确定接收后返回一个值,发送按钮变为灰色并倒计时. 运行效果: --------------------------------效果演

  • Android实现获取验证码倒计时功能

    本文实例为大家分享了android获取验证码倒计时功能的具体代码,供大家参考,具体内容如下 获取验证码倒计时在现在的App中非常常见,他主要的功能点就是给TextView设置一个点击事件,但是当点击后或出现倒计时,在倒计时的时候点击是触发不了点击事件的. 等倒计时结束显示重新获取验证码的时候可以重新触发点击事件: 在真实的项目中一般都是设置一分钟,咱们这里就不设置那么长了,设置10秒: 首先说下我这个demo非常简单,工具类不用管,直接复制到项目中,只需要两步两行代码即可: 第一步:初始化工具类

  • android实现一个图片验证码倒计时功能

    1.如图所示,要实现一个验证码的倒计时的效果          2.实现 图中获取验证码那块是一个button按钮 关键部分,声明一个TimeCount,继承自CountDownTimer /*验证码倒计时*/ private class TimeCount extends CountDownTimer{ /** * @param millisInFuture 总时间长度(毫秒) * @param countDownInterval 时间间隔(毫秒),每经过一次时间间隔都会调用onTick方法

  • Android 简单封装获取验证码倒计时功能

    效果如下图所示: 如图所示的效果相信大家都不陌生,我们可以使用很多种方法去实现此效果,这里自己采用 CountDownTimer 定时器简单封装下此效果,方便我们随时调用. 首页先在 attrs.xml 中定义下所需的几个属性: <resources> <declare-styleable name="CountDownButton"> <attr name="millisinfuture" format="integer&q

随机推荐