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)擊了,更推薦?。?!
但是傳入的參數(shù)必須是一個(gè)promise函數(shù)!!
//自定義指令版本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í)間格式總結(jié)以及轉(zhuǎn)換方法詳解
項(xiàng)目中后臺(tái)返回的時(shí)間有多種形式,時(shí)間戳、ISO標(biāo)準(zhǔn)時(shí)間格式等,我們需要轉(zhuǎn)化展示成能看的懂得時(shí)間格式,下面這篇文章主要給大家介紹了關(guān)于vue時(shí)間格式總結(jié)以及轉(zhuǎn)換方法的相關(guān)資料,需要的朋友可以參考下2022-12-12解決vue-router進(jìn)行build無(wú)法正常顯示路由頁(yè)面的問(wèn)題
下面小編就為大家分享一篇解決vue-router進(jìn)行build無(wú)法正常顯示路由頁(yè)面的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-03-03vue.js學(xué)習(xí)之vue-cli定制腳手架詳解
這篇文章主要給大家介紹了vue.js學(xué)習(xí)之vue-cli定制腳手架的相關(guān)資料,文中介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編一起來(lái)學(xué)習(xí)學(xué)習(xí)吧。2017-07-07創(chuàng)建Vue項(xiàng)目以及引入Iview的方法示例
這篇文章主要介紹了創(chuàng)建Vue項(xiàng)目以及引入Iview的方法示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-12-12vue-cli3.0 axios跨域請(qǐng)求代理配置方式及端口修改
這篇文章主要介紹了vue-cli3.0 axios跨域請(qǐng)求代理配置方式及端口修改,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10vue項(xiàng)目在webpack2實(shí)現(xiàn)移動(dòng)端字體自適配功能
這篇文章主要介紹了vue項(xiàng)目在webpack2實(shí)現(xiàn)移動(dòng)端字體自適配的相關(guān)知識(shí),本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06