有时,我们想要响应式数据具有一些特殊的效果,比如想让数据等1s
之后再显示到界面,但仍保持数据的响应式
我们可以借助vue3
里的一个API
来实现 —— customRef
# 介绍
vue3
官方文档对于customRef
的描述如下:
function customRef<T>(factory: CustomRefFactory<T>): Ref<T>
type CustomRefFactory<T> = (
track: () => void,
trigger: () => void
) => {
get: () => T
set: (value: T) => void
}
customRef
接受一个回调函数作为参数,然后这个回调函数又有两个参数 —— track
和trigger
,最后要返回一个对象,这个对象要包含两个函数 —— get
和set
其实我们可以发现,如果我们想要实现自定义需求,那就离不开get
和set
这两个函数
# 使用
现在实现我们上边说的那个需求,输入数据1s
后,显示数据
我们的自定义ref如下
trigger()
:在set
中使用,修改后数据后,告诉Vue重新解析模板track()
:在get
中使用,用来分辨是否是set
修改了数据,如果是,则返回newVal
// ./utils/useMyRef.js
import { customRef } from "vue";
export function useMyRef(value, delay) {
let timeout;
return customRef((track, trigger) => {
return {
get() {
track(); // 告诉get这个改变是通过set里的trigger进行触发的,返回修改后的newVal
return value;
},
set(newValue) {
clearTimeout(timeout);
timeout = setTimeout(() => {
value = newValue;
trigger(); // 告诉vue要重新解析模板
}, delay);
},
};
});
}
在App.vue
中调用useMyRef
钩子,然后设置delay
为1000
<template>
<input type="text" v-model="text" />
<h2>{{ text }}</h2>
</template>
<script setup>
import { useMyRef } from "./utils/myRef.js";
const text = useMyRef("hello", 1000);
</script>
初始效果如下
我们输入w,发现过了1s后,下面的数据才修改,保持了响应性
# 总结
在我们有自定义需求时,就可以配置一个自定义ref
,同时配合钩子一起使用是很方便的