编程 Vue3 自定义 `ref` —— `customRef` 的使用

2024-11-18 10:05:40 +0800 CST views 587

Vue3 自定义 ref —— customRef 的使用

本文介绍了Vue3中customRefAPI的使用,解释了其在控制响应式数据更新时的优势,特别是实现延迟更新的功能。通过示例代码,展示了如何创建一个带有延迟更新的ref,并将其封装为可复用的Hook,简化开发过程。customRef使得开发者能够灵活控制数据的读取和写入时机,提升响应式数据的使用效率。

一、为什么需要 customRef

Vue 提供了 refreactive 来定义响应式数据,但有时我们不希望视图立即更新,比如需要延迟更新。这种情况下,单纯使用 ref 是无法实现的。

举个例子

假设我们在一个 input 中双向绑定一个响应式数据,当用户输入时,数据会立即更新,视图也随之变化。但如果我们希望延迟更新该数据或控制更新频率,customRef 就可以发挥作用了。

二、customRef 的使用

首先,我们需要从 vue 中引入 customRef

import { customRef } from 'vue';

如何使用 customRef

customRef 是一个函数,它接受一个回调函数作为参数。回调函数要求返回一个对象,且该对象必须包含 getset 两个方法。

  • get:在数据被读取时调用。
  • set:在数据被修改时调用。

基本结构示例:

const delayedRef = customRef((track, trigger) => {
  let value;
  
  return {
    get() {
      track(); // 跟踪数据的依赖
      return value;
    },
    set(newValue) {
      value = newValue;
      trigger(); // 触发更新
    }
  };
});

三、延迟更新的实现

为了展示 customRef 的强大功能,我们可以实现一个延迟更新的例子。假设用户输入内容后,只有在停止输入一段时间后数据才会更新。

示例代码:

<template>
  <div>
    <input v-model="name" placeholder="输入内容后稍等更新"/>
    <p>当前值: {{ name }}</p>
  </div>
</template>

<script>
import { customRef } from 'vue';

export default {
  setup() {
    const useDebouncedRef = (value, delay = 300) => {
      let timeout;
      return customRef((track, trigger) => {
        return {
          get() {
            track(); // 跟踪依赖
            return value;
          },
          set(newValue) {
            clearTimeout(timeout);
            timeout = setTimeout(() => {
              value = newValue;
              trigger(); // 延迟后触发更新
            }, delay);
          }
        };
      });
    };

    const name = useDebouncedRef(''); // 使用自定义的延迟ref

    return {
      name
    };
  }
};
</script>

解释:

  • useDebouncedRef 是一个封装好的 hook,它创建了一个带有延迟更新的 ref
  • set 方法中,我们使用 setTimeout 实现延迟更新,只有当输入停止一段时间后,数据才会更新到视图中。

四、如何封装 customRef 为一个 Hook?

在开发中,customRef 经常会被封装成 hook 以便复用。让我们将上述延迟更新逻辑封装成一个 Hook。

创建 useDebouncedRef.js 文件

import { customRef } from 'vue';

export function useDebouncedRef(value, delay = 300) {
  let timeout;
  
  return customRef((track, trigger) => {
    return {
      get() {
        track(); // 跟踪依赖
        return value;
      },
      set(newValue) {
        clearTimeout(timeout);
        timeout = setTimeout(() => {
          value = newValue;
          trigger(); // 延迟后触发更新
        }, delay);
      }
    };
  });
}

使用封装好的 Hook

在任何需要的地方引入并使用这个 Hook,简化代码:

<template>
  <div>
    <input v-model="name" placeholder="输入内容后稍等更新"/>
    <p>当前值: {{ name }}</p>
  </div>
</template>

<script>
import { useDebouncedRef } from './useDebouncedRef';

export default {
  setup() {
    const name = useDebouncedRef(''); // 使用自定义的延迟ref

    return {
      name
    };
  }
};
</script>

五、总结

通过 customRef,我们可以灵活地控制数据的读取和写入时机,实现像延迟更新等高级功能。在实际开发中,customRef 可以帮助我们创建更加自定义和高效的响应式数据。封装为 Hook 后,使用也非常方便。

复制全文 生成海报 Vue 前端开发 JavaScript

推荐文章

在Rust项目中使用SQLite数据库
2024-11-19 08:48:00 +0800 CST
软件定制开发流程
2024-11-19 05:52:28 +0800 CST
使用Ollama部署本地大模型
2024-11-19 10:00:55 +0800 CST
使用 sync.Pool 优化 Go 程序性能
2024-11-19 05:56:51 +0800 CST
资源文档库
2024-12-07 20:42:49 +0800 CST
Vue中的`key`属性有什么作用?
2024-11-17 11:49:45 +0800 CST
PHP如何进行MySQL数据备份?
2024-11-18 20:40:25 +0800 CST
java MySQL如何获取唯一订单编号?
2024-11-18 18:51:44 +0800 CST
Nginx 跨域处理配置
2024-11-18 16:51:51 +0800 CST
liunx宝塔php7.3安装mongodb扩展
2024-11-17 11:56:14 +0800 CST
记录一次服务器的优化对比
2024-11-19 09:18:23 +0800 CST
如何在 Vue 3 中使用 Vuex 4?
2024-11-17 04:57:52 +0800 CST
HTML和CSS创建的弹性菜单
2024-11-19 10:09:04 +0800 CST
nuxt.js服务端渲染框架
2024-11-17 18:20:42 +0800 CST
快手小程序商城系统
2024-11-25 13:39:46 +0800 CST
Nginx 如何防止 DDoS 攻击
2024-11-18 21:51:48 +0800 CST
JavaScript 实现访问本地文件夹
2024-11-18 23:12:47 +0800 CST
JavaScript设计模式:单例模式
2024-11-18 10:57:41 +0800 CST
FcDesigner:低代码表单设计平台
2024-11-19 03:50:18 +0800 CST
前端如何一次性渲染十万条数据?
2024-11-19 05:08:27 +0800 CST
Vue中的异步更新是如何实现的?
2024-11-18 19:24:29 +0800 CST
对多个数组或多维数组进行排序
2024-11-17 05:10:28 +0800 CST
程序员茄子在线接单