防抖函数基本原理:setTimeout和clearTimeout的运用
关键代码:
let timer:any=null;
if(timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
// ...略
}, delay);
防抖函数钩子文件:
- import { ref, watch, type Ref, type UnwrapRef, onUnmounted } from "vue";
-
- // 优化抖动问题
- interface IDebounceFn<T> {
- (...args : T[]) : void | Promise<void>
- }
-
- // 普通防抖函数(利用setTimeout, clearTimeout, 闭包)
- export const debounceFn = <T>(fn: IDebounceFn<T>, delay: number) => {
- let timer:any = null;
- function f(this:void, ...args:T[]) {
- if(timer) {
- clearTimeout(timer)
- }
- timer = setTimeout(() => {
- fn.call(this, ...args);
- }, delay);
- }
- return f;
- }
-
- // 钩子函数可以使用很多vue自带的比如watch, computed, ref, 生命周期钩子等(如果要用于react, 就使用react相关的钩子, 生命周期等, 基本逻辑差不多)
- const useDebounce=<T>(value:Ref<T>, delay:number)=> {
- const debounceValue = ref(value.value)
- let timer:any=null;
- const unwatch = watch(
- value,
- (nv) => {
- if(timer) {
- clearTimeout(timer)
- }
- timer = setTimeout(() => {
- debounceValue.value = nv as UnwrapRef<T>
- }, delay);
- }
- )
-
- onUnmounted(() => {
- // 避免一直watch
- unwatch()
- })
-
- return debounceValue;
- }
-
- export default useDebounce;
使用普通防抖函数debounceFn的时候:
- const searchValue = ref(''); // 存储输入框的值
- const bounceWatch = (nv:string)=> {
- if(!nv) {
- // 搜索结果清空, 代码略
- }
- // 触发搜索函数, 代码略
- }
- watch(searchValue, debounceFn(bounceWatch, 1000)); // 监听输入框的值,防止调用太多查询接口,输入完成后才调用接口查询
使用useDebounce钩子函数时:
- const searchValue = ref(''); // 存储输入框的值
- const bounceWatch = (nv:string)=> {
- if(!nv) {
- // 搜索结果清空, 代码略
- }
- // 触发搜索函数, 代码略
- }
-
- // 利用防抖函数获取搜索框的值,再监听该值,输入完成后再调用查询接口
- const debounceValue = useDebounce(searchValue, 1000)
- watch(debounceValue, bounceWatch)