关键词: vue3,typescript
<template>
<!-- age有响应式,值的改变会更新页面 -->
<div>{{ obj.age }}</div>
<!-- info.pos没有响应式,值的改变不会更新页面, -->
<!-- 但age的改变会导致页面更新,因此info.pos也会更新 -->
<!-- (造成了info.pos也是响应式的假象) -->
<div>{{ obj.info.pos }}</div>
</template>
<script lang="ts">
import {
defineComponent,
isReactive,
onMounted,
shallowReactive,
} from "vue";
export default defineComponent({
name: "App",
setup() {
const obj = shallowReactive({
age: 100,
year: 0,
info: {
pos: 999,
},
});
console.log("obj>>>>", isReactive(obj.info));
setInterval(() => {
// age和info.pos都会响应式地显示在页面上,
// 本来应该是:age响应式显示,info.pos不会
obj.age++;
obj.info.pos++;
// 改为以下代码即可:
// // obj.age++; // 注释了obj.age++
// obj.info.pos++;
}, 1000);
return {
obj
};
},
});
</script>
原因
shallowReactive() 返回的对象 obj 为浅响应式,它跟踪其自身 property 的响应性(即第一层,如 obj.age );但不执行嵌套对象的深层(如 obj.info.pos )响应式转换 ,会暴露其原始值。
obj 只是不会响应式显示在屏幕,它在程序中还是会一直执行着 ++ 。
obj.age 和 obj.info.pos 通处于一个环境,都被同个Fragment包着,obj.age++触发改变,对应的模板领域会进行更新,所以页面给相当于重新渲染了一遍。如果obj.age没有在模板中用到,其值的变化不会触发重新渲染。
注释掉obj.age++的原因是:取消这个响应性值的变化而导致的页面更新。避免了obj.info.pos 也是响应式的假象。
参考: