toRaw
,将响应式对象(由 reactive
定义的响应式)转换为普通对象。
markRaw
,标记一个对象,使其不能成为一个响应式对象。
使用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
- 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} from "vue";
export default {
name:"Demo",
setup(){
let person = reactive({
name:"张三",
age:25
})
function addOtherInfo(){
person.otherInfo = {
position:"前端工程师",
salary:30
}
}
function changePosition(){
person.otherInfo.position = "后端工程师";
}
function changeSalary(){
person.otherInfo.salary++;
}
return {
person,
addOtherInfo,
changePosition,
changeSalary
}
}
}
</script>
- 启动应用,测试效果
通过person.otherInfo
的方式,给响应式对象person新增了属性otherInfo。
otherInfo属性值是一个对象:{ position:"前端工程师", salary:30 }
,该对象随person一起也成为了一个响应式对象。因此,当修改person.otherInfo.position
或person.otherInfo.salary
时,界面也随之更新。如下图所示。
使用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
时,界面不会更新。如下图所示。