有时,我们想要响应式数据具有一些特殊的效果,比如想让数据等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,同时配合钩子一起使用是很方便的
