我们使用 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>

结尾

最后,如果你觉得写法不对,欢迎指教

Logo

前往低代码交流专区

更多推荐