快速了解toRaw和markRaw的用法

toRaw

toRaw,将响应式对象(由 reactive定义的响应式)转换为普通对象。

  • 作用:将一个由reactive生成的响应式对象转为普通对象
  • 使用场景:用于读取响应式对象对应的普通对象,对这个普通对象的所有操作,不会引起页面更新。

toRaw示例一

​ 在代码中我们声明了一个对象 然后将对象传入reactive方法 返回一个响应式的对象 随后我们将person 响应式的对象 通过toRaw方法变回了普通对象 随后为了验证 变会的普通的对象 是不是我们最开始定义的对象 我们进行了一次输出

<template>
  <div>
    <h1>姓名:{{ p.name }}</h1>
    <h2>年龄:{{ p.age }}</h2>
    <h3>喜欢的水果:{{ p.likeFood.fruits.apple }}</h3>
    <button @click="p.name += '~'">修改姓名</button>
    <button @click="p.age++">修改年龄</button>
    <button @click="p.likeFood.fruits.apple += ''">修改水果</button>
  </div>
</template>
 
<script>
import { reactive, toRaw } from "vue";
export default {
  name: "App",
  setup() {
    // 定义了一段数据
    let data = {
      name: "张三",
      age: 18,
      likeFood: {
        fruits: {
          apple: "苹果",
        },
      },
    }
    // 将普通对象变为响应对象
    let person = reactive(data);
    // 将响应对象变为普通对象
    let p = toRaw(person)
 
    // 打印 data 是否等于 p 
    console.log(p === data);    // true
    // 将数据返回出去
    return {
      p
    };
  },
};
</script>

在浏览器中我们可以看到 打印信息为真 点击修改按钮 修改数据后页面也不做出响应了

img

toRaw示例二

  • main.js

import { createApp } from 'vue'
import App from './App.vue'

createApp(App).mount('#app')
  • App.vue
<template>
  <Demo/>
</template>
<script>
    import Demo from './components/Demo.vue'
    export default {
      name: 'App',
      components: {
        Demo
      }
    }
</script>
  • Demo.vue
<template>
  <h2>姓名:{{person.name}}</h2>
  <h2>年龄:{{person.age}}</h2>
  <h2>薪酬:{{person.job.salary}}K</h2>
  <button @click="person.age++">增长年龄</button>&nbsp;
  <button @click="person.job.salary++">涨薪</button>&nbsp;
  <button @click="showRawPerson">点我显示原始person</button>
</template>
<script>
import {reactive, toRaw} from "vue";
export default {
      name:"Demo",
      setup(){
        let person = reactive({
          name:"张三",
          age:25,
          job:{
            salary:30
          }
        })
    function showRawPerson(){
      console.log("person=",person);
      let p = toRaw(person);
      console.log("raw person = ",p);
    }

    return {
      person,
      showRawPerson
    }
  }
}
</script>
  • 启动应用,测试效果
    person,是由reactive定义的响应式对象。
    toRaw(person)后,响应式对象person就变成了一个普通对象。如下图所示。

img

markRaw

markRaw,标记一个对象,使其不能成为一个响应式对象。

我们在代码中声明了一个响应式对象 我们现在对象上添加一属性而这个属性的值被修改之后不需要页面的更新

我们知道直接在一个响应式的对象上添加属性也会被处理为响应式的,所以我们通过了markRaw()方法先将对象处理为一个永远不会再成为响应式对象 在添加在p对象上

markRaw示例一

<template>
  <div>
    <h1>姓名:{{ p.name }}</h1>
    <h2>年龄:{{ p.age }}</h2>
    <h3>喜欢的水果:{{ p.likeFood.fruits.apple }}</h3>
    <button @click="p.name += '~'">修改姓名</button>
    <button @click="p.age++">修改年龄</button>
    <button @click="p.likeFood.fruits.apple += ''">修改水果</button>
  </div>
</template>
 
<script>
import { reactive, markRaw } from "vue";
export default {
  name: "App",
  setup() {
    // 定义了一段数据
    let p = reactive({
      name: "张三",
      age: 18,
    });
    // 在p对象上直接添加一个对象会处理为响应式的 所一使用markRaw()使其永远不会再成为响应式对象。
    p.likeFood = markRaw({
      fruits: {
        apple: "苹果",
      },
    });
 
    // 将数据返回出去
    return {
      p,
    };
  },
};
</script>
 
 

我们在修改这个对象上的属性时页面就不会在触发更新了

img

markRaw示例二

  • main.js
import { createApp } from 'vue'
import App from './App.vue'

createApp(App).mount('#app')
  • App.vue
<template>
  <Demo/>
</template>
<script>
import Demo from './components/Demo.vue'
export default {
  name: 'App',
  components: {
    Demo
  }
}
</script>
  • Demo.vue
<template>
  <h2>姓名:{{person.name}}</h2>
  <h2>年龄:{{person.age}}</h2>
  <div v-if="person.otherInfo" style="background:skyblue;margin-bottom:10px">
    <h4>岗位:{{person.otherInfo.position}}</h4>
    <h4>薪酬:{{person.otherInfo.salary}}K</h4>
    <button @click="changePosition">调整岗位</button>&nbsp;
    <button @click="changeSalary">增加薪酬</button>
  </div>
  <button @click="addOtherInfo">增加其他信息</button>
</template>
<script>
import {reactive,markRaw} from "vue";
export default {
  name:"Demo",
  setup(){
    let person = reactive({
      name:"张三",
      age:25
    })
    function addOtherInfo(){
      person.otherInfo = markRaw({
        position:"前端工程师",
        salary:30
      })
    }

    function changePosition(){
      person.otherInfo.position = "后端工程师";
    }

    function changeSalary(){
      person.otherInfo.salary++;
    }

    return {
      person,
      addOtherInfo,
      changePosition,
      changeSalary
    }
  }
}
</script>
  • 启动应用,测试效果
    通过person.otherInfo的方式,给响应式对象person新增了属性otherInfo
    otherInfo属性值是一个由markRaw包裹的对象,即markRaw({ position:"前端工程师", salary:30 })
    markRaw{ position:"前端工程师", salary:30 }变成了一个非响应式对象。因此,当修改person.otherInfo.positionperson.otherInfo.salary时,界面不会更新。如下图所示。

img

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值