vue3发送验证码倒计时 (防止连点、封装复用)
创始人
2024-03-03 20:16:52
0

一、实现思路

倒计时 流程图

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

//倒计时初始变量
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 -1codeNum.value--;// 时间=0时 清除定时器 if (codeNum.value == 0) {clearInterval(clearId);// 还原 倒计时60scodeNum.value = 60;}}, 1000);
};

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

三、优化 

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

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

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

页面中使用

 

补充 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 }

 

相关内容

热门资讯

双阳法院:运用调解方式 化解行... 随着法治建设的深入推进,人民群众的法治意识和维权意识不断提高,行政案件逐渐增长,而行政争议发生在“官...
凌源钢铁股份有限公司关于诉讼进... 本公司董事会及全体董事保证本公告内容不存在任何虚假记载、误导性陈述或者重大遗漏,并对其内容的真实性、...
苏州瀚川智能科技股份有限公司 ... 证券代码:688022 证券简称:瀚川智能 公告编号:2025-097 苏州瀚川智能科技股份有限公司...
三部门:不断完善学前教育成本分... 观点网讯:12月23日,国家发展改革委、教育部、财政部联合发布《关于完善幼儿园收费政策的通知》,要求...
汪清林区法院:化解未成年人纠纷... 近日,吉林省汪清林区法院审结了一起涉未成年人在校遭受人身损害案件,法院充分考量了未成年人的行为特点及...
北京市长城保护条例 北京市人民代表大会常务委员会公告 〔十六届〕第45号 《北京市长城保护条例》已由北京市第十六届人民代...
棒杰股份(002634)披露关... 截至2025年12月23日收盘,棒杰股份(002634)报收于5.28元,较前一交易日下跌4.52%...
高盛再度唱多!预计中国股市到2... 来源:视觉中国 界面新闻编辑 | 江怡曼 近日,高盛发布名为《中国策略:2025年中国股市十大...
尤文身价变化:共10人身价下降... 在意甲联赛的激烈竞争中,尤文图斯的球员身价变化引发了广泛关注。根据最新的德转数据,尤文队内有10名球...
美国发布H-1B签证新规,优先... 当地时间12月23日,美国国土安全部发布新规,正式以“加权选择”机制取代H-1B签证原有的随机抽签制...