我们使用 vue 时,有时候需要用到自定义指令,例如一个防抖指令
前言
现在有一个需求,用户在点击某个按钮时,我不希望用户在疯狂点击后,每次点击都会触发事件,像服务器发送请求,这并不是我们预期的,所以我们需要在用户点击是做防抖处理。那么怎么做到方便复用的解决方法?还真有,那就是自己定义指令
一、在 main 中使用自定义指令
import useDebounce from '@/hooks/useDebounce'
const app = createApp(App)
app.directive('debounce', useDebounce)
下面是 useDebounce 代码
/**
* 防抖指令
* @param el 指令绑定的元素
* @param binding 指令绑定的值
* @param binding.value.callback 回调函数
* @param binding.value.params 回调函数参数
* @param binding.value.delay 延迟时间
* @example
* <button v-debounce="{callback: handleLike, params: { test: 0 }}">防抖</button> handleLike 为函数 params 为传入的参数
*/
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 || 1000
timer = setTimeout(
() => {
const { callback, params } = binding.value
// callback 不是函数
if (!callback || typeof callback !== 'function') {
throw new Error('callback is not a function')
}
callback(params ? params : e)
// 重置计时器
timer = null
},delay )
})
}
}
二、在页面中使用
<template>
<button v-debounce="{callback: handleClick , params: { test: 0 }}">点击我</button>
</template>
<script setup lang="ts">
// 你的函数
const handleClick = ({ test }: { test: number }) => {
console.log("防抖函数",test);
// ... 这里写你组件的逻辑
}
</script>
结尾
最后,如果你觉得写法不对,欢迎指教