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>
在浏览器中我们可以看到 打印信息为真 点击修改按钮 修改数据后页面也不做出响应了
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>
<button @click="person.job.salary++">涨薪</button>
<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
就变成了一个普通对象。如下图所示。
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>
我们在修改这个对象上的属性时页面就不会在触发更新了
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>
<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.position
或person.otherInfo.salary
时,界面不会更新。如下图所示。