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

customRef

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

用途

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

工作原理

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

  • 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++;
};

解释:

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

与 ref 的区别

ref

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

customRef

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

应用场景

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

实例 1

**目的:**我们可以通过触发countergetter来获取本地存储的值,即直接counter.value就能获取到了,而不是通过调用一个方法。同样地,我们也可以通过触发countersetter来设置本地存储的值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多平台发布

相关推荐
Zheng1131 小时前
【可视化大屏】将柱状图引入到html页面中
javascript·ajax·html
john_hjy1 小时前
【无标题】
javascript
软件开发技术深度爱好者2 小时前
用HTML5+CSS+JavaScript庆祝国庆
javascript·css·html5
汪子熙2 小时前
Angular 服务器端应用 ng-state tag 的作用介绍
前端·javascript·angular.js
昨天;明天。今天。8 小时前
案例-表白墙简单实现
前端·javascript·css
安冬的码畜日常8 小时前
【玩转 JS 函数式编程_006】2.2 小试牛刀:用函数式编程(FP)实现事件只触发一次
开发语言·前端·javascript·函数式编程·tdd·fp·jasmine
小御姐@stella8 小时前
Vue 之组件插槽Slot用法(组件间通信一种方式)
前端·javascript·vue.js
GISer_Jing8 小时前
【React】增量传输与渲染
前端·javascript·面试
GISer_Jing8 小时前
WebGL在低配置电脑的应用
javascript
万叶学编程11 小时前
Day02-JavaScript-Vue
前端·javascript·vue.js