随着Vue3中Composition API的引入,有了编写响应式逻辑的新方法,即​​ref​​​和​​reactive​​​方法。在本文中,将展示如何创建一个防抖的​​ref​​​,该​​ref​​​将在指定的延迟后才更新值。例如,有一个带有自动完成功能的搜索框,在该字段中搜索查询状态更改后发起API请求,那么防抖的​​ref​​就会非常有用。

防抖是一种不错的优化方式,如果没有这种方式,则每次点击后都会发起API请求。

实例代码仓库:github.com/QuintionTan…

使用Composition API在Vue3中创建防抖的搜索输入框_回调函数

开始

为了完成这个实例,将采用Vite创建一个新项目。可以通过运行​​yarn create @vitejs/app debounced-search​​​ 或者​​npm init @vitejs/app debounced-search​​​,然后选择​​Vue​​模板。执行完后将生成基础的项目目录结构。

使用Composition API在Vue3中创建防抖的搜索输入框_搜索_02

src/App.vue

正如上面说的,当搜索框中中输入搜索条件时,可以使用防抖引用来延迟API请求。

在模板中,有一个label、input和包含关键字query的div。完成后,将看到值只有在延迟之后才被更新。在​​setup​​​方法中,使用​​useDebouncedRef​​​函数创建一个​​debounce ref​​​,并传递一个空字符串作为初始值和数值500,500是debounce的延迟。除此之外,还有一个观察器来观察查询​​ref​​。这就是可以初始化一个函数来执行发起API请求的地方。

useDebouncedRef.js

下面是组件​​useDebouncedRef​​的实现代码:

import { ref, customRef } from "vue";

/**
*
* @param {*} fn 回调函数
* @param {*} delay 延迟毫秒数
* @param {*} immediate 是否立即执行
* @returns
*/
const debounce = (fn, delay = 0, immediate = false) => {
let timeout;
return (...args) => {
if (immediate && !timeout) fn(...args);
clearTimeout(timeout);

timeout = setTimeout(() => {
fn(...args);
}, delay);
};
};

const useDebouncedRef = (initialValue, delay, immediate) => {
const state = ref(initialValue);
const debouncedRef = customRef((track, trigger) => ({
get() {
track();
return state.value;
},
set: debounce(
(value) => {
state.value = value;
trigger();
},
delay,
immediate
),
}));
return debouncedRef;
};

export default useDebouncedRef;

在 ​​useDebouncedRef.js​​​ 文件中有两个方法 ​​deounce​​​ 和 ​​useDebouncedRef​​​ 函数。​​debounce​​​函数实现在指定的延迟时间过后执行回调函数。除了回调函数和延迟时间,它还接受第三个名为​​immediate​​的参数,用来指示回调是否应该立即执行。这个函数可以抽象到通用方法文件中,在应用程序的其他部分中调用。

​useDebouncedRef​​​ 方法中,使用了vue包中的​​ref​​​方法声明一个新的响应值,使用 ​​customRef​​​方法,来创建一个自定义的 ​​ref​​​,并对其依赖项跟踪和更新触发进行显式控制。它需要一个工厂函数,该函数接收 ​​track​​​ 和 ​​trigger​​​ 函数作为参数,并应返回一个带有 ​​get​​​ 和 ​​set​​ 的对象。