开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第13天,点击查看活动详情
toRaw和markRaw用来处理响应式对象和普通对象之间的转换的,其中toRaw是将响应式对象转成普通的原生对象,而markRaw是直接定义一个普通的原生对象,并且这个对象永远不能被转成响应式。
toRaw
toRaw是返回reactive或readonly proxy的原始对象。也就是说将一个由reactive生成的响应式对象转为普通对象。这是一个转义口,可用于临时读取而不会引起 proxy 访问/跟踪开销,也可用于写入而不会触发更改。
toRaw的用法
<template>
<div class="hello">
<div>姓名:{{person.name}}</div>
<div>年龄:{{person.age}}</div>
<div>朋友:{{person.friend.name}}-{{person.friend.age}}</div>
<div v-for="(item, index) in person.hobbies" :key="index">爱好列表
<div>{{item}}</div>
</div>
<button @click="updateInfo">修改信息</button>
</div>
</template>
<script setup>
import { reactive, toRaw } from 'vue';
let person = {
name: '艾薇儿',
age: 18,
friend: {
name: '安妮·海瑟薇',
age: '28'
},
hobbies: ['music', 'dance', 'movie']
};
const reactivePerson = reactive(person);
console.log('person', person);
console.log('reactivePerson', reactivePerson);
console.log(toRaw(reactivePerson) === person);
const updateInfo = () => {
person.friend.name = '疯驴子';
console.log('person', person);
console.log('reactivePerson', reactivePerson);
}
</script>
效果如下:
修改之后的效果如下:
此时toRaw(reactivePerson)就是个普通对象,只是这个对象是通过响应式对象转过来的。
toRaw的使用场景
用于读取响应式对象对应的普通对象,对这个普通对象的所有操作,不会引起页面更新。
markRaw
标记一个对象,使其永远不会转换为proxy。返回对象本身。
markRaw的用法
<template>
<div class="hello">
<div>姓名:{{person.name}}</div>
<div>年龄:{{person.age}}</div>
<div>朋友:{{person.friend.name}}-{{person.friend.age}}</div>
<div v-for="(item, index) in person.hobbies" :key="index">爱好列表
<div>{{item}}</div>
</div>
<button @click="updateInfo">修改信息</button>
</div>
</template>
<script setup>
import { markRaw, reactive, isReactive } from 'vue';
let person = markRaw({
name: '艾薇儿',
age: 18,
friend: {
name: '安妮·海瑟薇',
age: '28'
},
hobbies: ['music', 'dance', 'movie']
});
console.log('person', person);
console.log('isReactive', isReactive(reactive(person)));
const updateInfo = () => {
person.friend.name = '疯驴子';
console.log('person', person);
}
</script>
初始效果:
修改数据之后效果:
此时person就相当于是一个普通对象,而且这个对象永远不能转成响应式对象。
markRaw的应用场景
- 有些值不应被设置为响应式的,如第三方库,组件等
- 当渲染具有不可变数据源的大列表时,可以不使用响应性,从而提高性能