vue3.x之toRaw和markRaw

toRaw和markRaw用来处理响应式对象和普通对象之间的转换的,其中toRaw是将响应式对象转成普通的原生对象,而markRaw是直接定义一个普通的原生对象,并且这个对象永远不能被转成响应式。

toRaw

toRaw是返回reactive或readonly proxy的原始对象。也就是说将一个由reactive生成的响应式对象转为普通对象。这是一个转义口,可用于临时读取而不会引起 proxy 访问/跟踪开销,也可用于写入而不会触发更改。

toRaw的用法

<template>
  <div>姓名:{{ person.name }}</div><br>
  <div>年龄:{{ person.age }}</div><br>
  <div>朋友:{{ person.friend.name }}-{{ person.friend.age }}</div><br>
  <div v-for="(item, index) in person.hobbies" :key="index">爱好列表
    <div>{{ item }}</div>
  </div><br>
  <button @click="updateInfo">修改信息</button>
</template>

<script lang="ts">
//👀:需要什么导入什么
import { reactive, toRaw } from 'vue'
export default {
  name: 'App',
  //setup函数是组合式API的入口函数,调用在beforeCreated之前
  setup() {
    //1.定义响应式变量
    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);
    //2.定义函数
    const updateInfo = () => {
      person.friend.name = '疯驴子';
      console.log('person', person);
      console.log('reactivePerson', reactivePerson);
    }
    return { person, updateInfo, reactivePerson }
  }
}
</script>

效果如下:

修改之后的效果如下:

此时toRaw(reactivePerson)就是个普通对象,只是这个对象是通过响应式对象转过来的。

toRaw的使用场景

用于读取响应式对象对应的普通对象,对这个普通对象的所有操作,不会引起页面更新。

markRaw

标记一个对象,使其永远不会转换为proxy。返回对象本身。

markRaw的用法

<template>
  <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>
</template>

<script lang="ts">
//👀:需要什么导入什么
import { reactive, isReactive, markRaw } from 'vue'
export default {
  name: 'App',
  //setup函数是组合式API的入口函数,调用在beforeCreated之前
  setup() {
    //1.定义响应式变量
    let person = markRaw({
      name: '艾薇儿',
      age: 18,
      friend: {
        name: '安妮·海瑟薇',
        age: '28'
      },
      hobbies: ['music', 'dance', 'movie']
    });
    console.log('person', person);
    console.log('isReactive', isReactive(reactive(person)));
    //2.定义函数
    const updateInfo = () => {
      person.friend.name = '疯驴子';
      console.log('person', person);
    }
    return { person, updateInfo }
  }
}
</script>

初始效果:

 
修改数据之后效果:

 

此时person就相当于是一个普通对象,而且这个对象永远不能转成响应式对象。

markRaw的应用场景

1. 有些值不应被设置为响应式的,如第三方库,组件等
2. 当渲染具有不可变数据源的大列表时,可以不使用响应性,从而提高性能

posted on 2024-07-11 17:56  梁飞宇  阅读(124)  评论(0)    收藏  举报