你知道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 小时前
Vue插槽
前端·javascript·vue.js
qq_448011165 小时前
Vue + Jinja2两套模版与法冲突造成undefinedError
前端·javascript·vue.js
FRing038 小时前
JavaScript入门到精通三十二(深拷贝、浅拷贝、递归函数)
开发语言·前端·javascript
兰亭妙微UI设计公司10 小时前
兰亭妙微ui设计公司分享:B端组件命名如何支持团队协作
前端·javascript·vue.js
小大宇11 小时前
Vue知识点-ElementPlus-03提示框+询问+通知
前端·javascript·vue.js
前端技术官12 小时前
前端的技术判断力是怎么练出来的?
javascript·web前端·localstorage·debounce·弱网处理
程序员大阳13 小时前
副队长JavaScript教程(60)-BOM 初识:window 对象与浏览器模型
javascript·bom·window对象·浏览器模型
web打印社区13 小时前
Chrome-kiosk-printing能上生产吗
开发语言·前端·javascript·chrome·websocket
志尊宝14 小时前
AI原生前端开发(041):AI辅助的状态管理(Zustand/Pinia)
前端·javascript·ai-native
Geoffwo14 小时前
DSH-SKILL基础
javascript