在vue3中通过hooks方式封装节流和防抖

734 阅读2分钟

创建 useThrottle Hook

节流函数的作用是确保一个函数在一段时间内只能被执行一次,即使它被连续调用多次也只会执行一次。

Javascript
深色版本
import { ref, onBeforeUnmount } from 'vue';

function useThrottle(callback, delay = 100) {
  let timerId = ref(null);

  const cancel = () => {
    if (timerId.value !== null) {
      clearTimeout(timerId.value);
      timerId.value = null;
    }
  };

  const throttledCallback = (...args) => {
    if (!timerId.value) {
      timerId.value = setTimeout(() => {
        callback(...args);
        timerId.value = null;
      }, delay);
    }
  };

  onBeforeUnmount(cancel); // 在组件卸载前清除定时器

  return [throttledCallback, cancel];
}

export default useThrottle;

创建 useDebounce Hook

防抖函数则是确保在一个给定的时间段内,只有最后一次操作会触发函数执行,如果在这段时间内还有新的操作发生,则重新计时。

Javascript
深色版本
import { ref, onBeforeUnmount } from 'vue';

function useDebounce(callback, delay = 100) {
  let timerId = ref(null);

  const cancel = () => {
    if (timerId.value !== null) {
      clearTimeout(timerId.value);
      timerId.value = null;
    }
  };

  const debouncedCallback = (...args) => {
    cancel(); // 取消之前的定时器
    timerId.value = setTimeout(() => {
      callback(...args);
    }, delay);
  };

  onBeforeUnmount(cancel); // 在组件卸载前清除定时器

  return [debouncedCallback, cancel];
}

export default useDebounce;

解析

  • useThrottle: 这个 hook 接受一个回调函数 callback 和一个延迟时间 delay。它返回一个被节流的函数 throttledCallback,这个函数在首次调用后会设置一个定时器,在 delay 时间之后执行 callback 并重置定时器。此外,它还返回了一个 cancel 函数用来取消定时器。
  • useDebounce: 类似于 useThrottle,但是它在每次调用 debouncedCallback 时都会先取消任何未完成的定时器,然后再设置一个新的定时器。这意味着只有在最后一次调用后的 delay 时间结束后,callback 才会被执行。

在 Vue 组件中使用这些 hooks

Vue
深色版本
<template>
  <div>
    <button @click="handleClick">Click me</button>
    <p>Clicked at: {{ lastClickTime }}</p>
  </div>
</template>

<script>
import useThrottle from './useThrottle';
import useDebounce from './useDebounce';

export default {
  setup() {
    const lastClickTime = ref('');
    const handleAction = () => {
      lastClickTime.value = new Date().toISOString();
    };

    // 使用节流
    const [handleClickThrottled] = useThrottle(handleAction, 500);

    // 或者使用防抖
    // const [handleClickDebounced] = useDebounce(handleAction, 500);

    return {
      lastClickTime,
      handleClick: handleClickThrottled,
      // 或者使用防抖版本
      // handleClick: handleClickDebounced,
    };
  },
};
</script>

这样,每次点击按钮时,节流或防抖处理函数就会被调用,并更新 lastClickTime。你可以根据需要选择使用节流或防抖处理函数。