vue.js

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > vue.js > vue3防抖hook

基于vue3实现防抖hook的示例代码

作者:白菜豆腐花

这篇文章主要为大家详细介绍了如何基于vue3实现防抖hook,文中的示例代码简洁易懂,具有一定的参考价值,感兴趣的小伙伴可以跟随小编一起学习一下

vue3实现防抖hook

包装函数并延迟执行,避免频繁触发,常用于前端页面搜索框优化处理(只在输入停止的时候才去执行相应的操作)

src/hook/useDebounce.ts

import { ref, watch } from 'vue';

/**
 * 防抖 Hook
 * @param fn - 需要防抖的函数
 * @param delay - 延迟时间(毫秒),默认300ms
 * @returns 包含防抖函数和清除定时器的方法
 */
export function useDebounce<T extends (...args: any[]) => any>(
  fn: T,
  delay: number = 300
) {
  // 存储定时器ID
  const timer = ref<NodeJS.Timeout | null>(null);

  // 防抖处理函数,保持原函数的参数类型
  const debouncedFn = (...args: Parameters<T>): void => {
    // 清除已有定时器
    if (timer.value) {
      clearTimeout(timer.value);
    }

    // 设置新定时器
    timer.value = setTimeout(() => {
      fn.apply(this, args);
      timer.value = null;
    }, delay);
  };

  // 组件卸载时清除定时器,防止内存泄漏
  watch(
    () => {},
    () => {
      if (timer.value) {
        clearTimeout(timer.value);
      }
    },
    { once: true }
  );

  // 手动清除定时器的方法
  const clearDebounce = (): void => {
    if (timer.value) {
      clearTimeout(timer.value);
      timer.value = null;
    }
  };

  return { debouncedFn, clearDebounce };
}
    

应用

import { ref } from "vue";
import { useDebounce } from "@/hook/useDebounce";
const handleSearch = keyword => {
  console.log("搜索:", keyword);
  // 实际的搜索逻辑...
};
// 在输入框变化时调用防抖函数、使用防抖Hook,延迟500ms
const { debouncedFn: debouncedSearch } = useDebounce(handleSearch, 500);
      <el-input
        v-model="searchValue"
        placeholder="请输入内容"
        @input="debouncedSearch"
      />

其他

ref<NodeJS.Timeout | null>(null)

ref:Vue3 提供的创建响应式数据的函数,会将传入的值包装为一个响应式对象(Ref 类型),方便在组件中追踪其变化。

<NodeJS.Timeout | null> :TypeScript 的类型注解,指定 ref 存储的值类型只能是两种之一:

NodeJS.Timeout:Node.js 环境中定时器的类型(setTimeout 的返回值类型),表示一个活跃的定时器实例。

null:表示没有活跃的定时器(初始状态或定时器已被清除)。

(null) :初始化 ref 的值为 null,即初始状态下没有定时器。

T extends (...args: any[]) => any 

是 TypeScript 中的泛型约束,用于限制泛型 T 的类型范围,具体含义如下:

拆解说明:

T:是定义的泛型变量,代表 “某种类型”,具体类型会在使用时动态确定。

extends:泛型约束关键字,表示 “T 必须是某种类型的子类型”。

(...args: any[]) => any:一个函数类型的 “模板”,表示:

方法补充

Vue3自定义防抖Hook

在Vue3中,使用自定义防抖Hook是一种常见的优化手段,用于控制高频触发的事件(如输入、滚动、点击等),以避免性能问题。以下是关于如何在Vue3中使用自定义防抖Hook的详细说明:

自定义防抖Hook的实现

自定义防抖Hook通常通过闭包和定时器来实现,确保在指定时间内只执行一次处理函数。以下是一个基本的防抖Hook实现:

import { ref, onUnmounted } from 'vue'

export function useDebounce<T>(fn: (...args: any[]) => void, delay: number) {
  let timer: ReturnType<typeof setTimeout> | null = null

  const debouncedFn = (...args: any[]) => {
    if (timer) clearTimeout(timer)
    timer = setTimeout(() => {
      fn(...args)
      timer = null
    }, delay)
  }

  onUnmounted(() => {
    if (timer) clearTimeout(timer)
  })

  return debouncedFn
}

在组件中使用防抖Hook

在Vue3组件中,可以导入并使用自定义的防抖Hook。以下是一个使用防抖Hook的示例:

<script setup>
import { ref } from 'vue'
import { useDebounce } from './useDebounce'

const searchQuery = ref('')

// 创建防抖函数,延迟500毫秒执行
const debouncedSearch = useDebounce((query) => {
  console.log('执行搜索:', query)
  // 这里可以调用API进行搜索
}, 500)

const handleInput = (e) => {
  searchQuery.value = e.target.value
  debouncedSearch(searchQuery.value)
}
</script>

<template>
  <input @input="handleInput" placeholder="搜索..." />
</template>

防抖Hook的注意事项

1.清理定时器的详细说明

实现细节:

完整示例代码:

const timer = ref(null)
const debounceFn = () => {
  clearTimeout(timer.value)
  timer.value = setTimeout(() => {
    // 业务逻辑
  }, 500)
}
onUnmounted(() => {
  clearTimeout(timer.value)
})

重要性分析:

2.取消防抖的扩展实现

完整扩展方法:

完整实现示例:

const useDebounce = () => {
  const timer = ref(null)
  
  const cancel = () => {
    if(timer.value) {
      clearTimeout(timer.value)
      timer.value = null
      console.log('防抖已取消')
    }
  }

  const debounce = (fn, delay) => {
    cancel()
    timer.value = setTimeout(fn, delay)
  }

  return { debounce, cancel }
}

使用场景说明:

3.防抖时间设置的详细规范

场景化推荐值:

场景类型推荐时间(ms)说明
搜索联想300-500平衡响应速度和请求压力
UI布局调整100-200保证视觉流畅性
按钮防重150-300防止误操作同时保持响应

调整原则细则:

防抖Hook的应用场景深度解析

1.搜索框输入 联想优化

典型实现方案:

const { debounce } = useDebounce()
const search = (query) => {
  // API调用逻辑
}
watch(inputValue, (newVal) => {
  debounce(() => search(newVal), 400)
})

优化效果数据:

2.窗口大小调整最佳实践

具体实现案例:

const resizeHandler = () => {
  // 重绘图表逻辑
  // 调整布局样式
}
window.addEventListener('resize', 
  debounce(resizeHandler, 200)
)

性能对比数据:

场景原始调用次数防抖后调用次数
拖动调整窗口120+3-5
最大化/还原8-101

3.按钮防重复提交方案

完整实现示例:

const submitOrder = () => {
  loading.value = true
  debounce(async () => {
    try {
      await api.submitOrder()
    } finally {
      loading.value = false
    }
  }, 300)()
}

效果评估:

4.其他应用场景技术细节

滚动事件处理:

window.addEventListener('scroll', 
  debounce(loadMoreContent, 250)
)

自动保存功能:

watch(formData, 
  debounce(autoSave, 1000),
  { deep: true }
)

5.特殊注意事项

移动端适配:

关键操作规范:

操作类型最大建议时间
支付确认≤200ms
表单提交≤300ms
重要状态变更≤150ms

测试方法 论:

到此这篇关于基于vue3实现防抖hook的示例代码的文章就介绍到这了,更多相关vue3防抖hook内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文