在vue3项目中利用自定义ref实现防抖
一,效果展示
自定义ref实现防抖效果
二,代码部分
1在app.vue中
<template>
<input v-model="text"/>
<p class="result">{{text}}</p>
</template>
<script setup>
import {debounceRef} from './unitls/debounceRef.js'
import {ref} from 'vue'
const text = debounceRef('',1000)
</script>
<style scoped>
</style>
2,在debounceRef.js中
import {customRef} from 'vue';
export function debounceRef(value,delay=1000){
let timer;
return customRef((track,trigger)=>({
get(){
// 依赖收集
track();
return value;
},
set(val){
clearTimeout(timer);
timer = setTimeout(()=>{
// 派发更新
value = val;
trigger();
},delay);
},
}));
}
三,代码解释
1. `import {customRef} from 'vue';` 这行代码是一个 `ES6` 模块的导入语句,从 `Vue` 库中导入了 `customRef` 这个函数。在 `Vue` 中,`customRef` 是一个用于创建自定义引用类型的工具函数,它允许开发者按照自己的需求来定义响应式数据的行为,比如控制数据的读取、更新等操作逻辑,使其更灵活地适应不同的业务场景。
2. `export function debounceRef(value,delay=1000){` 这里定义了一个名为 `debounceRef` 的函数,并通过 `export` 关键字将其导出,以便在其他模块中可以引入并使用该函数。这个函数接收两个参数: - `value`:表示要处理的初始值,这个值会和最终创建的自定义引用类型相关联,后续可以通过这个自定义引用类型进行读取和更新操作。 - `delay`:是一个可选参数,默认值为 `1000`(单位应该是毫秒),用于指定防抖的延迟时间,即当数据更新时,会延迟一定时间后才真正去执行更新操作,在此期间如果有新的更新操作触发,会重新计时延迟。
3. `let timer;` 在 `debounceRef` 函数内部声明了一个变量 `timer`,它用于存储定时器的标识。在后续实现防抖功能时,会借助 `setTimeout` 创建定时器来控制更新操作的延迟执行,而这个变量就是用来保存定时器的返回值(以便后续能通过 `clearTimeout` 来清除定时器)。
4. `return customRef((track,trigger)=>({` 这行代码开始返回一个由 `customRef` 创建的自定义引用类型。`customRef` 函数接收一个回调函数作为参数,这个回调函数又接收两个参数 `track` 和 `trigger`,它们的作用如下: - `track`:是一个函数,用于进行依赖收集。在自定义引用类型的 `get` 方法中调用它,能够告知 `Vue` 哪些地方使用了这个引用类型的数据,以便当数据变化时,相关依赖的地方能够正确地收到更新通知并重新渲染。 - `trigger`:同样是一个函数,用于触发视图更新。在自定义引用类型的 `set` 方法中,当满足一定条件(比如防抖延迟结束后)需要通知 `Vue` 去更新使用了该数据的相关视图时,调用这个函数来触发更新操作。 整体这行代码返回的是一个包含 `get` 和 `set` 方法的对象,这两个方法定义了自定义引用类型的数据读取和更新行为。
5. `get(){` 这是自定义引用类型对象中的 `get` 方法定义,当在模板或者其他地方读取这个自定义引用类型所关联的数据时,就会触发这个 `get` 方法。
6. `// 依赖收集` 这是一个注释,用于提示下面这行代码的作用是进行依赖收集。
7. `track();` 在 `get` 方法内调用 `track` 函数,正如前面所述,它的作用是告诉 `Vue` 在这里使用了这个自定义引用类型的数据,`Vue` 会记录这个依赖关系,以便后续数据变化时能正确地更新相关依赖的地方。
8. `return value;` 这行代码将传入 `debounceRef` 函数的初始 `value` 返回,也就是当读取这个自定义引用类型时,实际获取到的值就是最初传入的那个 `value` 。
9. `set(val){` 这是自定义引用类型对象中的 `set` 方法定义,当尝试更新这个自定义引用类型所关联的数据时(比如通过赋值操作),就会触发这个 `set` 方法。这里的 `val` 参数就是要更新的值。
10. `clearTimeout(timer);` 在 `set` 方法中,首先调用 `clearTimeout` 函数并传入之前声明的 `timer` 变量,目的是清除可能已经存在的定时器。因为如果在延迟时间还没结束时又有新的更新操作触发,就需要先把之前的定时器清除掉,重新开始计时延迟,以实现防抖的效果。
11. `timer = setTimeout(()=>{` 这行代码创建一个新的定时器,通过 `setTimeout` 函数来实现。它接收一个箭头函数作为参数,这个箭头函数内的代码会在延迟指定的 `delay` 时间(毫秒)后执行,也就是在防抖延迟结束后执行的逻辑。
12. `// 派发更新` 这是一个注释,提示下面代码的作用是进行更新的派发操作,也就是触发视图更新。
13. `value = val;` 在定时器的回调函数内,将传入 `set` 方法的更新值 `val` 赋给最初传入 `debounceRef` 函数的 `value` 变量,实现了对数据的更新操作。
14. `trigger();` 调用 `trigger` 函数,正如前面所讲,它用于通知 `Vue` 去更新使用了该自定义引用类型数据的相关视图,触发视图更新,使得数据变化能够反映到页面上。
15. `},delay);` 这是 `setTimeout` 函数调用的结尾部分,指定了前面设置的定时器的延迟时间,也就是按照传入 `debounceRef` 函数的 `delay` 参数(默认 `1000` 毫秒)来设置延迟,确保在延迟时间结束后才执行更新操作及触发视图更新。
四,总结
总的来说,这段代码定义了一个名为 `debounceRef` 的函数,利用 `Vue` 中的 `customRef` 函数创建了一个具有防抖功能的自定义引用类型。在实际使用中,通过这个自定义引用类型进行数据读取和更新时,更新操作会按照设定的防抖延迟时间来执行,避免频繁触发更新,适用于一些例如输入框输入内容后延迟搜索等需要防抖的业务场景。