vue3 响应式API toRaw() 和 markRaw()

toRaw()

toRaw()根据一个 Vue 创建的代理返回其原始对象。

toRaw() 可以返回由 reactive()readonly()shallowReactive() 或者 shallowReadonly() 创建的代理对应的原始对象。

官网描述:这是一个可以用于临时读取而不引起代理访问/跟踪开销,或是写入而不触发更改的特殊方法。不建议保存对原始对象的持久引用,请谨慎使用。

示例:

import { reactive, toRaw } from 'vue';
const reactiveObj = reactive({ message: 'Hello' });
const rawObj = toRaw(reactiveObj);
console.log(rawObj); // 输出原始对象,没有响应式的特性

在这里插入图片描述
toRaw接受一个响应式对象作为参数,并返回该对象的原始版本,即没有被 Vue 的响应式系统包裹的版本。

使用场景

在需要将响应式对象传递给非 Vue 的库或外部系统时,使用 toRaw() 可以确保它们收到的是普通对象。

markRaw()

markRaw()将一个对象标记为不可被转为代理,使其永远不会变成响应式的。即使这个对象被传递给reactiveref等响应式函数,它也不会被转换为响应式对象。

markRaw()接受一个对象作为参数,并且返回该对象本身。

import { markRaw, reactive } from 'vue';
const normalObj = { message: 'Hello' };
const markedObj = markRaw(normalObj);
const reactiveObj = reactive(markedObj);

console.log(reactiveObj); // 输出的对象仍然是非响应式的,不会触发依赖追踪和更新
console.log(isReactive(reactiveObj)) // false

const changeReactiveObjMsg = () => {
  // 不会触发响应式更新,因为 reactiveObj 被标记为非响应式
  reactiveObj.message = 'Change Reactive message!'
}

通过Vue Devtools查看setup里的数据:
从下图可以看出,reactiveObj是一个普通的对象,不是被Proxy包裹的响应式对象。
在这里插入图片描述

markRaw()是浅层的

markRaw()的作用是浅层的,这意味着它只会影响直接传入的对象本身,而不会递归地处理对象的嵌套属性。

  • 当使用 markRaw() 标记一个对象时,只有这个对象本身被标记为非响应式
  • 如果这个对象包含嵌套的对象或数组,这些嵌套的内容不会被自动标记为非响应式。
import { markRaw, reactive } from 'vue';
// 尽管 markedObj 被标记为了原始对象,但 markedObj.details 却没有
const markedObj = markRaw({
  name: '张三',
  age: 18,
  details: {
    address: '四川省成都市'
  }
});

// foo 是原始对象
const foo = reactive(markedObj);

// bar 是响应式对象
const bar = reactive({
  id: 'bar',
  details: markedObj.details
});

console.log(foo.details === bar.details)  // false

通过Vue Devtools查看setup里的数据:
在这里插入图片描述

使用场景

  1. 有些值不应该是响应式的,例如复杂的第三方类实例或 Vue 组件对象。
  2. 当呈现带有不可变数据源的大型列表时,跳过代理转换可以提高性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值