vue3發(fā)送驗證碼倒計時功能的實現(xiàn)(防止連點、封裝復用)
一、實現(xiàn)思路

二、實現(xiàn)一個簡單的驗證碼倒計時
//倒計時初始變量
const codeNum = ref(60);
// 定時器id
let clearId: number;
// 發(fā)送驗證碼
const sendCode = async () => {
// 防止下次點擊 如果倒計時的時間不是60 就不執(zhí)行下面邏輯
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);
};當然 這只是沒有做過優(yōu)化的一個發(fā)送驗證碼,如果要考慮點擊連續(xù)點擊或者離開頁面時銷毀定時器 還要加一些功能
三、優(yōu)化
(1)第一種方案,定義一個變量來控制 如果之前沒有點擊 再次點擊不再執(zhí)行
<script lang="ts" setup>
// 接口
import { getCode } from "@/api/login";
// 定時器id
let clearId:number;
// 倒計時時間
const codeNum = ref(60);
// 手機號
const mobile = ref("13230000001");
// 是否發(fā)送了驗證碼 防止連點
+ const isClickSend = ref(false);
// 發(fā)送驗證碼
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 ? "發(fā)送驗證碼" : `(${codeNum})發(fā)送驗證碼` }}</a>
</template>(2)第二種方案. 讓倒計時初始值為0 調(diào)用函數(shù)時在賦值為60 下次值大于0時同樣不再執(zhí)行,實現(xiàn)思路和第一種相似
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);
};其中沒有對手機號進行校驗 若需要則自己可以寫校驗規(guī)則,也可以參考當前使用的其他組件庫使用
離開頁面銷毀定時器
onMounted(() => {
clearInterval(clearId)
})四、邏輯封裝
為什么要封裝 驗證碼倒計時功能?
1. 為了下次再次使用時 直接copy代碼達到復用
2. 在日常開發(fā)中可能 有很多場景都需要發(fā)送驗證碼 只是 接口一樣 只是參數(shù)的type值不一樣 例如 登錄需要傳login 注冊需要傳register 到時候只需要調(diào)用更換參數(shù)即可
新建composable/index.ts 準備放公共方法
// 引用 發(fā)送的驗證碼類型
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
// 之后頁面調(diào)用send方法來使用
const send = async () => {
// 第二次點擊 大于0時 直接 return
if (timer.value > 0) return
// 校驗 mobile字段 要和 van-field 中的name保持一直 否則校驗失敗 如果校驗失敗則不走下面代碼 注意await
await form.value?.validate('mobile')
// 校驗通過調(diào)用接口
await getCode(mobile.value, type)
// 賦值倒計時 可修改成自己需要的時間
timer.value = 10
// 如果之前id存在可清除
if (timerId) clearInterval(timerId)
// 賦值定時器id
timerId = setInterval(() => {
// 時間-1
timer.value--
// 倒計時結(jié)束 清除定時器
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 ? "發(fā)送驗證碼" : `(${timer})后發(fā)送驗證碼` }}
</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位數(shù)字' }
]
export { mobileRules, passwordRules, codeRules }到此這篇關于vue3發(fā)送驗證碼倒計時 (防止連點、封裝復用)的文章就介紹到這了,更多相關vue3驗證碼倒計時內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Ant?Design?of?Vue?select框獲取key和name的問題
這篇文章主要介紹了Ant?Design?of?Vue?select框獲取key和name的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-06-06
解決iview table組件里的 固定列 表格不自適應的問題
這篇文章主要介紹了解決iview table組件里的 固定列 表格不自適應的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-11-11

