Vue3 中ref、toRef、toRefs、isRef、unref、customRef、triggerRef、shallowRef

ref

  • 用途: ref 用于创建一个响应式的引用(Ref),可以是任意数据类型。
  • 使用场景: 适用于需要对一个简单数据(比如字符串、数字、布尔值等)进行响应式管理的场景。
  • 特点: ref 会将传入的值包装成一个对象,且这个对象的 .value 属性持有实际值。
import { ref } from 'vue';

// 创建一个响应式的数值 ref
const count = ref(0);

// 访问或修改值时,使用 .value
console.log(count.value); // 输出: 0
count.value++;
console.log(count.value); // 输出: 1

toRef

  • 用途: toRef 用于将一个对象的某个属性创建为一个响应式引用(Ref),从而允许直接操作该属性。
  • 使用场景: 当需要将某个对象的属性变为响应式,但又不想丢失原对象的响应式特性时使用。
  • 特点: 它只对对象的单个属性进行包装,并保持对原对象的引用。
import { reactive, toRef } from 'vue';

const state = reactive({ foo: 1, bar: 2 });

// 将 state 对象的 foo 属性转为 ref
const fooRef = toRef(state, 'foo');

console.log(fooRef.value); // 输出: 1

// 修改 fooRef 的值会影响原对象
fooRef.value = 10;
console.log(state.foo); // 输出: 10

toRefs

  • 用途: toRefs 将一个响应式对象中的所有属性转换为响应式引用(Ref)。
  • 使用场景: 当需要将整个对象解构赋值时使用,避免失去响应式能力。
  • 特点: 生成的每个属性都是 ref,从而保持对象解构时的响应式特性。
import { reactive, toRefs } from 'vue';

const state = reactive({ foo: 1, bar: 2 });

// 将 state 对象的所有属性转为 ref
const { foo, bar } = toRefs(state);

console.log(foo.value); // 输出: 1
console.log(bar.value); // 输出: 2

// 修改 foo 的值会影响原对象
foo.value = 10;
console.log(state.foo); // 输出: 10

isRef

  • 用途: 用于检查一个值是否是 ref 对象。
  • 使用场景: 当需要判断某个值是否是 ref 时使用,尤其在混合普通数据和响应式数据时非常有用。
import { ref, isRef } from 'vue';

const count = ref(0);
const notRef = 10;

console.log(isRef(count)); // 输出: true
console.log(isRef(notRef)); // 输出: false

unref

  • 用途: 用于解包 ref 对象,返回其内部的值;如果传入的不是 ref,则直接返回该值。
  • 使用场景: 当不确定值是否是 ref 时使用,可以统一解包出其实际值。
import { ref, unref } from 'vue';

const count = ref(0);
const notRef = 10;

console.log(unref(count)); // 输出: 0
console.log(unref(notRef)); // 输出: 10

customRef

  • 用途: customRef 允许你创建一个完全自定义的 ref,可以自定义响应性追踪和触发逻辑。
  • 使用场景: 当你需要对 ref 的依赖追踪和更新行为进行细粒度控制时使用,比如控制更新频率(防抖或节流)。
  • 特点: customRef 通过传入一个工厂函数,返回一个包含 get 和 set 方法的 ref,从而自定义其行为。
import { customRef } from 'vue';

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);
      },
    };
  });
}

const debouncedValue = useDebouncedRef('hello');
debouncedValue.value = 'world'; // 更新将被防抖处理

triggerRef

  • 用途: triggerRef 用于手动触发 ref 的依赖更新。
  • 使用场景: 当使用 shallowRef 或者其他情况下 ref 的值虽然没有变,但希望手动触发更新时使用。
  • 特点: 不改变 ref 的值,仅触发更新。
import { ref, triggerRef } from 'vue';

const shallowData = ref({ foo: 1 });

// 手动触发更新
triggerRef(shallowData);

shallowRef

  • 用途: shallowRef 创建一个浅层的响应式 ref,即只对 ref 的顶层数据进行响应式追踪,而不递归处理内部嵌套的对象属性。
  • 使用场景: 适用于性能优化场景,或当你不希望对对象内部的深层属性进行响应式追踪时使用。
  • 特点: 只在顶层进行响应式追踪,不影响内部的嵌套属性。
import { shallowRef } from 'vue';

const shallowObj = shallowRef({ foo: { bar: 1 } });

console.log(shallowObj.value.foo.bar); // 输出: 1

// 改变顶层对象,会触发响应式更新
shallowObj.value = { foo: { bar: 2 } };

// 改变深层次的值,不会触发响应式更新
shallowObj.value.foo.bar = 3; // 不会触发视图更新

总结

  • ref:创建一个响应式的引用对象。
  • toRef:将一个对象的某个属性转为响应式引用。
  • toRefs:将一个对象的所有属性转为响应式引用。
  • isRef:检查一个值是否是 ref 对象。
  • unref:解包 ref 对象,返回其内部的值。
  • customRef: 允许你自定义响应性行为,适合用于复杂的响应性逻辑(如防抖、节流)。
  • triggerRef: 手动触发 ref 的更新,适合在特殊情况下需要强制触发更新时使用。
  • shallowRef: 创建浅层响应式的 ref,仅追踪顶层数据,适合性能优化或避免深层响应性的场景。
  • 12
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值