你知道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多平台发布

相关推荐
吕彬-前端5 分钟前
使用vite+react+ts+Ant Design开发后台管理项目(五)
前端·javascript·react.js
学前端的小朱8 分钟前
Redux的简介及其在React中的应用
前端·javascript·react.js·redux·store
guai_guai_guai17 分钟前
uniapp
前端·javascript·vue.js·uni-app
也无晴也无风雨18 分钟前
在JS中, 0 == [0] 吗
开发语言·javascript
王哲晓1 小时前
第三十章 章节练习商品列表组件封装
前端·javascript·vue.js
理想不理想v2 小时前
‌Vue 3相比Vue 2的主要改进‌?
前端·javascript·vue.js·面试
酷酷的阿云2 小时前
不用ECharts!从0到1徒手撸一个Vue3柱状图
前端·javascript·vue.js
aPurpleBerry3 小时前
JS常用数组方法 reduce filter find forEach
javascript
ZL不懂前端3 小时前
Content Security Policy (CSP)
前端·javascript·面试
乐闻x3 小时前
ESLint 使用教程(一):从零配置 ESLint
javascript·eslint