自定义ref

2023/6/29

有时,我们想要响应式数据具有一些特殊的效果,比如想让数据等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接受一个回调函数作为参数,然后这个回调函数又有两个参数 —— tracktrigger,最后要返回一个对象,这个对象要包含两个函数 —— getset

其实我们可以发现,如果我们想要实现自定义需求,那就离不开getset这两个函数

# 使用

现在实现我们上边说的那个需求,输入数据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>

初始效果如下

1

我们输入w,发现过了1s后,下面的数据才修改,保持了响应性

2

3

# 总结

在我们有自定义需求时,就可以配置一个自定义ref,同时配合钩子一起使用是很方便的

How to love
Lil Wayne