你知道vue3的customRef吗?你知道它和ref的区别吗?你知道它的应用场景吗?

customRef

customRef() 是 Vue 3 中新增的 API,用于创建自定义 ref,并对其依赖项跟踪和更新触发进行显式控制。

用途

  • 实现防抖/节流:通过控制依赖项收集和更新触发时机,可以实现防抖/节流功能。
  • 自定义计算属性:可以根据特定逻辑计算值,并控制何时更新视图。
  • 优化性能:可以避免不必要的更新,提升性能。

工作原理

customRef() 接收一个工厂函数作为参数,该函数接收 track 和 trigger 两个函数作为参数,并返回一个带有 get 和 set 方法的对象。

  • track :用于收集依赖项。在 get 方法中调用,收集该 ref 所依赖的响应式数据。
  • trigger :用于触发更新。在 set 方法中调用,通知依赖项更新视图。

示例:

typescript 复制代码
const count = customRef((track, trigger) => {
  let num = 0;

  return {
    get: () => num,
    set: (val) => {
      num = val;
      trigger();
    },
  };
});

const update = () => {
  count.value++;
};

解释:

  • track 和 trigger 函数分别用于收集依赖项和触发更新。
  • get 方法返回当前值。
  • set 方法更新值并触发更新。

与 ref 的区别

ref

  • 是 Vue 3 中用于创建响应式变量的 API。
  • 更简单易用,适用于大多数场景。

customRef

  • 提供对依赖项跟踪和更新触发更细粒度的控制。
  • 更灵活,适用于需要更精细控制的场景。

应用场景

customRef允许我们通过获取或设置一个变量的值时进行一些额外的操作,而不需要侦听这个变量进行额外的操作。

实例 1

**目的:**我们可以通过触发counter的getter来获取本地存储的值,即直接counter.value就能获取到了,而不是通过调用一个方法。同样地,我们也可以通过触发counter的setter来设置本地存储的值counter.value=1

javascript 复制代码
<script setup>

import { customRef } from "vue";
function useLocalStorage(key: string, initialValue: any) {
  const value = customRef((track, trigger)=>{
    return {
      get(){
        track()
        return localStorage.getItem(key) ?? initialValue
      },
      set(v){
        localStorage.setItem(key, v)
        trigger()
      }
    }
  })

  return value
}

const counter = useLocalStorage("counter", 0)
const update = () => {
  counter.value++
}

</script>

<template>
  <p>Counter: {{ counter }}</p>
  <button @click="update">
    Update
  </button>
</template>

??是 ES11 中新增的运算符,表示当左边的操作数为 null 或 undefined 时,返回其右侧的操作数,否则返回左侧的操作数

实例 2

目的:实现一个防抖的 ref

javascript 复制代码
<script setup>
import { watch, customRef } from "vue"
function useDebouncedRef(delay = 500) {
  return customRef((track, trigger)=>{
    let timer
    let temp
    return {
      get(){
        track()
        return temp
      },
      set(v){
        timer && clearInterval(timer)
        timer = setInterval(()=>{
          temp = v
          trigger()
        }, delay)
      }
    }
  })
}
const text = useDebouncedRef()
watch(text, (value) => {
  console.log(value)
})
</script>

<template>
  <input v-model="text" />
</template>

本文由mdnice多平台发布

相关推荐
星栈5 小时前
pnpm 12 升级实测
前端·javascript
Ai-_Man6 小时前
您您这可以把Microsofat Copilot的多个会话比如说。左侧的多个会话一次性导出吗?不是单条会话里面的多次会对话。AI导出鸭
javascript·人工智能·ai·小程序·电脑·copilot
Bruce_Liuxiaowei9 小时前
网页版 DeepSeek “harness desktop“ WebGL 上下文创建失败排查实录
开发语言·javascript·webgl
小凯在掘金10 小时前
为什么箭头函数不能作为构造函数?
前端·javascript
可乐鸡翅yeah_10 小时前
网页端 M3U8 播放器性能监控,怎么看播放卡顿指标
javascript·ffmpeg·音视频·safari·m3u8
可乐鸡翅yeah_10 小时前
M3U8 防盗链 URL‑Token 签名,新手开发实操避坑
开发语言·javascript·ios·音视频·safari
2603_9658966210 小时前
JS原型与原型链|对象继承与实例底层原理
开发语言·javascript·原型模式
JustHappy11 小时前
「vConsole MCP🛠️」我让 AI 直接看见任何 H5 的日志和请求帮你 debug
前端·javascript·程序员
xieter12 小时前
【技术精选】Node.js 核心事件循环机制与异步 I/O 深度剖析 (2026-10-02)
前端·javascript
想吃火锅100512 小时前
【leetcode】238.除了自身以外数组的乘积js
javascript·算法·leetcode