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()
将一个对象标记为不可被转为代理,使其永远不会变成响应式的。即使这个对象被传递给reactive
或ref
等响应式函数,它也不会被转换为响应式对象。
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里的数据:
使用场景
- 有些值不应该是响应式的,例如复杂的第三方类实例或 Vue 组件对象。
- 当呈现带有不可变数据源的大型列表时,跳过代理转换可以提高性能。