vue3 shallowRef导致视图更新的问题解析
vue3 的 shallowRef API可以定义浅层响应式数据,也就是当修改第一层数据时,才会触发试图的更新,更深层的数据修改不会造成试图上的数据更新。
question:实际开发过程中会遇到 修改深层shallowRef定义的数据,导致了试图更新的bug,怎么造成的?
示例代码如下:
<template>
<h3 style="text-align: left">shallowRef造成试图更新</h3>
<button @click="changeName">changeName</button>
<p>{{ a }} ------------ {{ msg }}</p>
</template>
<script setup lang="ts">
import { ref, shallowRef } from "vue";
const a = ref("hello");
const msg = shallowRef({
name: "小白",
age: 3,
});
const changeName = () => {
a.value = "你好"; // 修改ref定义的响应式数据的值
msg.value.name = "小黑"; // 修改shallowRef定义的浅层响应式数据
console.log("msg", msg);
};
</script>
在浏览器内,在 a.value = "你好"
前面打个debug进入调试
可以发现修改a.value时候,触发了vue3响应式函数的setter函数,setter函数内检测到有数据改变了,会去调用triggerRefValue(this, newVal)
从而触发了试图的更新,所以当同时msg.value.name = "小黑"
修改shallowRef定义的深层数据时,由于试图被触发了,msg的最新数据也会被更新到视图上
结果如下:
所以当我们注释a.value = "你好"
之后,就能达到正常的预期,修改深层数据而不会触发试图更新;
官方推荐在修改shallowRef所定义的深层数据后,使用triggerRef()
去主动触发更新,而不是通过这种不规范的方式。