持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第16天,点击查看活动详情。
今天主要是学习readonly与shallowReadonly函数,toRaw与markRaw函数。
readonly
readonly深度只读数据,传入响应式或纯对象,返回一个原始对象的只读代理,对象内部任何嵌套的属性也都是只读的,在某些特定的情况下,不希望对数据进行更新的操作,那就可以包装生成一个只读代理对象来读取数据,防止对数据的修改或删除等操作。
示例: 定义一个只读对象,当对只读对象中的属性进行修改或者删除的时候,就会报错:
<script lang="ts">
import { defineComponent, readonly } from "vue";
export default defineComponent({
name: "readonly",
setup() {
let readState = readonly({
a: 1,
b: 2,
c: {
d: 4,
},
});
readState.a += 1; // 浅层不能修改
delete readState.c; // 浅层不能删除
return {
readState
}
},
});
</script>
shallowReadonly
shallowReadonly浅只读数据,传入响应式或者纯对象,返回一个原始对象的只读代理,但是这个只读只是第一层只读,非深度只读。
示例:
同样在使用shallowReadonly定义一个只读对象,当对只读对象中的属性进行修改或者删除的时候,a这个属性是第一层所以还是会报错;
在修改深层次的d属性的时候,是可以修改的;
let shallowReadState = shallowReadonly({
a: 1,
b: 2,
c: {
d: 4,
},
});
shallowReadState.a += 3; // 浅层不能修改
shallowReadState.c.d += 3; // 深层可以修改
delete shallowReadState.c.d; // 深层可以删除
console.log(shallowReadState)
不过删除d的时候也会报错,这时候我们还是可以解决这个问题的,在tsconfig.json中我们加上这样一句代码:"strictNullChecks":false,这时候去console,就发现d被删除了。
toRaw
toRaw可以将由reactive或者readonly函数转换成响应式代理的普通对象,对普通对象的属性值进行修改,就不会更新视图界面。一般用于渲染具有不可变数据源的大列表时,跳过代理转换可以提高性能。
示例:
<template>
<div>
<div>{{state.total}}</div>
<button @click="update">更新数据</button>
</div>
</template>
<script lang="ts">
import {
defineComponent,
readonly,
shallowReadonly,
reactive,
toRaw,
} from "vue";
export default defineComponent({
name: "readonly",
setup() {
let state = reactive({
total: 10,
});
let update = () => {
let stateRaw = state;
stateRaw.total += 100;
};
return {
state,
update
};
},
});
</script>
此时更新数据是可以正常更新的,但是使用toRaw的时候,就不能更新state了,常用于,在数据还需要其他处理的时候,使用toRaw这样就不会再界面进行响应式更新了。
let stateRaw = toRaw(state);
markRaw
markRaw标记一个对象 ,使其永远不会转换为响应式数据,只能返回这个对象本身,一般用于有些值不应被设置为响应式的,比如第三方实例或者Vue组件对象等场景。
let markState = markRaw({
arr:[1, 2,3]
});
let reactiveMarkState = reactive(markState);
let updateMark = ()=> {
reactiveMarkState.arr.push(4)
}
一旦使用markRaw标记一个对象,就不能再使用reactive进行转换,不过使用toRaw标记后,是可以用reactive进行再转换为响应式数据。
接下来继续学习Vue3的知识点~