背景
项目中多处出现重复提交调用接口,导致数据库存入多条相同数据
vue3
/**
* example
* params内可加自定义参数
* <button v-debounce="{callback: test, params: {time: 0}}">防抖点击</button>
* 接收参数
* const test = (params) => {
* const { time } = params
* console.log('执行')
* }
*
* @param binding.value.callback 回调函数
* @param binding.value.params 回调函数参数
* @param binding.value.delay 延迟时间
*/
export default {
mounted(el: HTMLElement, binding: { value: { callback: Function; params?: any; delay?: number } }) {
let timer: ReturnType<typeof setTimeout> | null = null;
el.addEventListener('click', (e: Event) => {
e.preventDefault();
// 阻止冒泡
e.stopPropagation();
if (timer) clearTimeout(timer);
let delay = binding.value?.delay || 500;
timer = setTimeout(() => {
const { callback, params } = binding.value;
if (!callback || typeof callback !== 'function') {
throw new Error('callback is not a function');
}
callback(params ? params : e);
timer = null;
}, delay);
});
}
}
这是vue2,不建议使用
首先书写一个指令方法
/**
* @debounce
* 按钮v-debounce防抖
*/
export default {
/** bind */
bind(el: any, binding: any, vnode: any) {
let wait = binding.value; // 防抖时间
if (!wait) {
// 默认时间2s
wait = 2000;
}
let timer: any = null;
el.addEventListener(
'click',
(event: any) => {
if (!timer) {
timer = setTimeout(() => {
timer = null;
}, wait);
} else {
clearTimeout(timer);
timer = setTimeout(() => {
timer = null;
}, wait);
// eslint-disable-next-line no-unused-expressions
event && event.stopImmediatePropagation();
}
},
true
);
}
};
然后在main.js引用该方法; Vue.directive('debounce', debounce);
使用
<el-button v-debounce>防抖提交</el-button>