VUE3自定義指令防止重復(fù)點(diǎn)擊多次提交的實(shí)現(xiàn)方法
VUE3自定義指令防止重復(fù)點(diǎn)擊多次提交
1.需求
vue3項(xiàng)目,新增彈框連續(xù)點(diǎn)擊確定按鈕防止多次提交,在按鈕上添加自定義指令
2.實(shí)現(xiàn)方式
reClick.ts文件 防止重復(fù)點(diǎn)擊方法,自定義指令
export default { mounted(el: any, binding: any) { el.addEventListener('click', () => { if (!el.disabled) { el.disabled = true setTimeout(() => { el.disabled = false }, binding.value || 3000) } }) } }
index.ts文件 引入多種自定義指令,包括防止重復(fù)點(diǎn)擊指令
import type { App } from 'vue'; import reClick from './reClick'; //引入其他指令 /** * 導(dǎo)出指令方法:v-xxx * @methods reClick 防止重復(fù)點(diǎn)擊,用法:v-reClick */ export function directive(app: App) { //連續(xù)點(diǎn)擊指令 v-reClick默認(rèn)3秒不能聯(lián)系點(diǎn)擊 v-reClick="1000" app.directive('reClick', reClick); }
main.ts全局引入
import App from './App.vue'; import {directive} from '@/directive/index.ts'; //引入自定義指令 const app = createApp(App); directive(app); //全局引入
vue文件使用
<!-- v-reClick 默認(rèn)3秒內(nèi)反正重復(fù)點(diǎn)擊 --> <el-button v-reClick type="primary" :disabled="loading">確定</el-button> <!-- v-reClick="1000" 默認(rèn)1秒內(nèi)反正重復(fù)點(diǎn)擊 --> <el-button v-reClick="1000" type="primary" :disabled="loading">確定</el-button>
補(bǔ)充:vue3——兩種利用自定義指令實(shí)現(xiàn)防止按鈕重復(fù)點(diǎn)擊的方法
vue3——兩種利用自定義指令實(shí)現(xiàn)防止按鈕重復(fù)點(diǎn)擊的方法
方法一:利用定時(shí)器設(shè)置時(shí)間,下方代碼設(shè)置時(shí)間為1秒
但是有個(gè)缺點(diǎn):請(qǐng)求如果很慢,1秒鐘還沒(méi)有好,那么該方法就沒(méi)用了
// 利用定時(shí)器:1秒之后才能再次點(diǎn)擊 app.directive('preventReClick', { mounted: (el, binding) => { el.addEventListener('click', () => { if (!el.disabled) { el.disabled = true setTimeout(() => { el.disabled = false }, binding.value || 1000) } }) } })
方法二:傳入請(qǐng)求的函數(shù)作為參數(shù),根據(jù)請(qǐng)求的finally來(lái)判斷是否可以點(diǎn)擊了,更推薦?。。?/strong>
但是傳入的參數(shù)必須是一個(gè)promise函數(shù)?。?/p>
//自定義指令版本2:根據(jù)請(qǐng)求結(jié)果防止按鈕重復(fù)提交請(qǐng)求 //使用方式如下: //1、請(qǐng)求函數(shù)不需要傳參,直接傳函數(shù)名或者包含函數(shù)名的對(duì)象,比如v-prevent-dup-click="submit"或者{fn:submit} //2、請(qǐng)求函數(shù)需要傳參,傳遞一個(gè)對(duì)象,包含函數(shù)名和參數(shù),比如{fn:submit,params:[1,2,3]} import type { App, Directive, DirectiveBinding } from 'vue' interface ReturnPromiseFn { (...args: any[]): Promise<any> } interface objectType { fn: ReturnPromiseFn params?: any[] } app.directive('preventDupClick', directiveBindingDirective) const directiveBindingDirective: Directive = { mounted(el, binding: DirectiveBinding<ReturnPromiseFn & objectType>) { if (!binding.value) { throw new Error('v-prevent-dup-click must pass a parameter') } if (typeof binding.value !== 'function' && typeof binding.value !== 'object') { throw new Error('v-prevent-dup-click requires a function or an object with a function `fn`') } // 一開(kāi)始是未點(diǎn)擊狀態(tài) el.isClicked = false const handerClick = function (event) { // 如果已經(jīng)點(diǎn)擊過(guò),則阻止事件 if (el.isClicked === 'true') { event.preventDefault() event.stopPropagation() return } // 標(biāo)記為已點(diǎn)擊 el.isClicked = 'true' // 調(diào)用傳入的函數(shù) let fn: ReturnPromiseFn let params: any[] = [] //如果只傳函數(shù)名 if (typeof binding.value == 'function') { fn = binding.value } else { //如果傳對(duì)象{fn:submit,params:[1,2,3]}或者{fn:submit} fn = (binding.value as objectType).fn params = (binding.value as objectType)?.params ?? [] } console.log(params, 'params') try { fn(...params).finally(() => { el.isClicked = false }) } catch (error) { throw new Error('binding.value或 binding.value.fn必須是返回Promise類型的函數(shù)') } } el.hander = handerClick el.addEventListener('click', handerClick) }, //銷毀事件 beforeUnmount(el) { if (el.hander) { el.removeEventListener('click', el.hander) } } }
到此這篇關(guān)于VUE3自定義指令防止重復(fù)點(diǎn)擊多次提交的文章就介紹到這了,更多相關(guān)vue3自定義指令防止重復(fù)點(diǎn)擊內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue將毫秒數(shù)轉(zhuǎn)化為正常日期格式的實(shí)例
今天小編就為大家分享一篇vue將毫秒數(shù)轉(zhuǎn)化為正常日期格式的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-09-09vue中使用過(guò)濾器filters的this為undefined的問(wèn)題
這篇文章主要介紹了vue中使用過(guò)濾器filters的this為undefined的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01vue3+elementPlus二次封裝表單的實(shí)現(xiàn)代碼
最近使用Vue3+ElementPlus開(kāi)發(fā)項(xiàng)目,從整體上構(gòu)思組件的封裝。能寫(xiě)成組件的內(nèi)容都進(jìn)行封裝,方便多個(gè)地方使用,這篇文章給大家介紹了vue3+elementPlus二次封裝表單的實(shí)現(xiàn),并通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-03-03vue項(xiàng)目中的遇錯(cuò):Invalid?Host?header問(wèn)題
這篇文章主要介紹了vue項(xiàng)目中的遇錯(cuò):Invalid?Host?header問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07Vue3中當(dāng)v-if和v-for同時(shí)使用時(shí)產(chǎn)生的問(wèn)題和解決辦法
封裝一個(gè)組件時(shí),我使用到了v-for和v-if,它們?cè)谕粯?biāo)簽內(nèi),總是提示v-for循環(huán)出來(lái)的item在實(shí)例中沒(méi)有被定義,查詢資料后原因是因?yàn)関-for和v-if在同級(jí)使用時(shí),v-if優(yōu)先級(jí)比v-for高,所以本文給大家介紹了Vue3中當(dāng)v-if和v-for同時(shí)使用時(shí)產(chǎn)生的問(wèn)題和解決辦法2024-07-07Vue中利用better-scroll組件實(shí)現(xiàn)橫向滾動(dòng)功能
橫向滾動(dòng)這個(gè)功能是我們?nèi)粘i_(kāi)發(fā)中經(jīng)常會(huì)遇到的一個(gè)需求,下面這篇文章主要給大家介紹了關(guān)于Vue中如何利用better-scroll組件實(shí)現(xiàn)橫向滾動(dòng)的相關(guān)資料,需要的朋友可以參考下2021-06-06vue中如何通過(guò)iframe方式加載本地的vue頁(yè)面
這篇文章主要介紹了vue中如何通過(guò)iframe方式加載本地的vue頁(yè)面,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09淺談Vue Element中Select下拉框選取值的問(wèn)題
下面小編就為大家分享一篇淺談Vue Element中Select下拉框選取值的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-03-03Vue3利用vue-plugin-hiprint插件實(shí)現(xiàn)無(wú)預(yù)覽打印功能
在MES管理系統(tǒng)中需要實(shí)現(xiàn)條碼數(shù)據(jù)從接口返回后,直接調(diào)用打印機(jī)進(jìn)行打印,跳過(guò)瀏覽器的預(yù)覽確定那一步,在嘗試很多JS的方式和插件后,都無(wú)法實(shí)現(xiàn)該功能,所以本文介紹了Vue3如何利用vue-plugin-hiprint插件實(shí)現(xiàn)無(wú)預(yù)覽打印功能,需要的朋友可以參考下2025-04-04