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

二、實(shí)現(xiàn)一個(gè)簡(jiǎn)單的驗(yàn)證碼倒計(jì)時(shí)
//倒計(jì)時(shí)初始變量 const codeNum = ref(60); // 定時(shí)器id let clearId: number; // 發(fā)送驗(yàn)證碼 const sendCode = async () => { // 防止下次點(diǎn)擊 如果倒計(jì)時(shí)的時(shí)間不是60 就不執(zhí)行下面邏輯 if (codeNum.value != 60) return; // 掉接口 const res = await getCode(mobile.value, "login"); // 把定時(shí)器賦值給 變量clearId 目的:清除定時(shí)器 clearId= setInterval(() => { // 每次 時(shí)間1s -1 codeNum.value--; // 時(shí)間=0時(shí) 清除定時(shí)器 if (codeNum.value == 0) { clearInterval(clearId); // 還原 倒計(jì)時(shí)60s codeNum.value = 60; } }, 1000); };
當(dāng)然 這只是沒有做過優(yōu)化的一個(gè)發(fā)送驗(yàn)證碼,如果要考慮點(diǎn)擊連續(xù)點(diǎn)擊或者離開頁(yè)面時(shí)銷毀定時(shí)器 還要加一些功能
三、優(yōu)化
(1)第一種方案,定義一個(gè)變量來控制 如果之前沒有點(diǎn)擊 再次點(diǎn)擊不再執(zhí)行
<script lang="ts" setup> // 接口 import { getCode } from "@/api/login"; // 定時(shí)器id let clearId:number; // 倒計(jì)時(shí)時(shí)間 const codeNum = ref(60); // 手機(jī)號(hào) const mobile = ref("13230000001"); // 是否發(fā)送了驗(yàn)證碼 防止連點(diǎn) + const isClickSend = ref(false); // 發(fā)送驗(yàn)證碼 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ā)送驗(yàn)證碼" : `(${codeNum})發(fā)送驗(yàn)證碼` }}</a> </template>
(2)第二種方案. 讓倒計(jì)時(shí)初始值為0 調(diào)用函數(shù)時(shí)在賦值為60 下次值大于0時(shí)同樣不再執(zhí)行,實(shí)現(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); };
其中沒有對(duì)手機(jī)號(hào)進(jìn)行校驗(yàn) 若需要?jiǎng)t自己可以寫校驗(yàn)規(guī)則,也可以參考當(dāng)前使用的其他組件庫(kù)使用
離開頁(yè)面銷毀定時(shí)器
onMounted(() => { clearInterval(clearId) })
四、邏輯封裝
為什么要封裝 驗(yàn)證碼倒計(jì)時(shí)功能?
1. 為了下次再次使用時(shí) 直接copy代碼達(dá)到復(fù)用
2. 在日常開發(fā)中可能 有很多場(chǎng)景都需要發(fā)送驗(yàn)證碼 只是 接口一樣 只是參數(shù)的type值不一樣 例如 登錄需要傳login 注冊(cè)需要傳register 到時(shí)候只需要調(diào)用更換參數(shù)即可
新建composable/index.ts 準(zhǔn)備放公共方法
// 引用 發(fā)送的驗(yàn)證碼類型 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'; // 封裝方法 只需要傳入手機(jī)號(hào)、 type類型 export const useSendCode = (mobile: Ref<string>, type: CodeType) => { // 定義定時(shí)器初始值為0 const timer = ref(0) // 定義form變量 如果用了vant 記得要給vanForm 綁定ref const form = ref<FormInstance | null>() ; // 定義定時(shí)器id 為了清除定時(shí)器 let timerId: number // 之后頁(yè)面調(diào)用send方法來使用 const send = async () => { // 第二次點(diǎn)擊 大于0時(shí) 直接 return if (timer.value > 0) return // 校驗(yàn) mobile字段 要和 van-field 中的name保持一直 否則校驗(yàn)失敗 如果校驗(yàn)失敗則不走下面代碼 注意await await form.value?.validate('mobile') // 校驗(yàn)通過調(diào)用接口 await getCode(mobile.value, type) // 賦值倒計(jì)時(shí) 可修改成自己需要的時(shí)間 timer.value = 10 // 如果之前id存在可清除 if (timerId) clearInterval(timerId) // 賦值定時(shí)器id timerId = setInterval(() => { // 時(shí)間-1 timer.value-- // 倒計(jì)時(shí)結(jié)束 清除定時(shí)器 if (timer.value == 0) clearInterval(timerId) }, 1000) } // onMounted(() => { clearInterval(timerId) }) return { timer, send, form } }
由于代碼中使用了插件 沒有引入ref onMounted 需要可自行引入
頁(yè)面中使用
<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="請(qǐng)輸入手機(jī)號(hào)" :rules="mobileRule" /> </van-form> ... <a href="javascript:;" rel="external nofollow" rel="external nofollow" @click="sendCode" > {{ timer == 0 ? "發(fā)送驗(yàn)證碼" : `(${timer})后發(fā)送驗(yàn)證碼` }} </a> </template>
補(bǔ)充 mobileRule
import type { FieldRule } from 'vant' const mobileRules: FieldRule[] = [ { required: true, message: '請(qǐng)輸入手機(jī)號(hào)' }, { pattern: /^1[3-9]\d{9}$/, message: '手機(jī)號(hào)格式不正確' } ] const passwordRules: FieldRule[] = [ { required: true, message: '請(qǐng)輸入密碼' }, { pattern: /^\w{8,24}$/, message: '密碼需8-24個(gè)字符' } ] const codeRules: FieldRule[] = [ { required: true, message: '請(qǐng)輸入驗(yàn)證碼' }, { pattern: /^\d{6}$/, message: '驗(yàn)證碼為6位數(shù)字' } ] export { mobileRules, passwordRules, codeRules }
到此這篇關(guān)于vue3發(fā)送驗(yàn)證碼倒計(jì)時(shí) (防止連點(diǎn)、封裝復(fù)用)的文章就介紹到這了,更多相關(guān)vue3驗(yàn)證碼倒計(jì)時(shí)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Vue3實(shí)現(xiàn)獲取驗(yàn)證碼按鈕倒計(jì)時(shí)效果
- Vue3動(dòng)態(tài)倒計(jì)時(shí)的代碼實(shí)現(xiàn)
- Vue3+Hooks實(shí)現(xiàn)4位隨機(jī)數(shù)和60秒倒計(jì)時(shí)的示例代碼
- vue3實(shí)現(xiàn)封裝時(shí)間計(jì)算-日期倒計(jì)時(shí)組件-還有XX天&第XX天
- 基于Vue3創(chuàng)建一個(gè)簡(jiǎn)單的倒計(jì)時(shí)組件
- Vue3?實(shí)現(xiàn)驗(yàn)證碼倒計(jì)時(shí)功能
- Vue3?實(shí)現(xiàn)驗(yàn)證碼倒計(jì)時(shí)功能(刷新保持狀態(tài))
- 使用Vue3實(shí)現(xiàn)倒計(jì)時(shí)器及倒計(jì)時(shí)任務(wù)的完整代碼
相關(guān)文章
axios請(qǐng)求中以params或body形式傳遞參數(shù)的區(qū)別淺析
最近在做自己項(xiàng)目中,做一個(gè)非常簡(jiǎn)單的新增用戶場(chǎng)景,但是使用原生axios發(fā)送post請(qǐng)求的時(shí)候,還是踩了不少坑的,下面這篇文章主要給大家介紹了關(guān)于axios請(qǐng)求中以params或body形式傳遞參數(shù)的區(qū)別的相關(guān)資料,需要的朋友可以參考下2023-04-04vue中優(yōu)雅實(shí)現(xiàn)數(shù)字遞增特效的詳細(xì)過程
項(xiàng)目中需要做數(shù)字滾動(dòng)增加的效果,一開始很懵,研究了一下原理,發(fā)現(xiàn)很簡(jiǎn)單,下面這篇文章主要給大家介紹了關(guān)于vue中優(yōu)雅實(shí)現(xiàn)數(shù)字遞增特效的詳細(xì)過程,需要的朋友可以參考下2022-12-12Vue?Router動(dòng)態(tài)路由實(shí)現(xiàn)實(shí)現(xiàn)更靈活的頁(yè)面交互
Vue?Router是Vue.js官方的路由管理器,用于構(gòu)建SPA(單頁(yè)應(yīng)用程序),本文將深入探討Vue?Router的動(dòng)態(tài)路由功能,希望可以幫助大家更好地理解和應(yīng)用Vue.js框架2024-02-02關(guān)于Vue.js一些問題和思考學(xué)習(xí)筆記(2)
這篇文章主要為大家分享了關(guān)于Vue.js一些問題和思考的學(xué)習(xí)筆記,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-12vue+tp5實(shí)現(xiàn)簡(jiǎn)單登錄功能
這篇文章主要為大家詳細(xì)介紹了vue+tp5實(shí)現(xiàn)簡(jiǎn)單登錄功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11