前言
在尝试Vue.js的官网文档案例中发现
运用 @click 事件改变ref以及shallowRef的时候发现会同时进行
过程复现
首先我们来举一个例子
vue
<script setup lang="ts">
import {ref,shallowRef} from 'vue'
const msgRef = ref({mgs:'a'})
const mgsShallowRef = shallowRef({mgs:'b'})
cosnt change = () => {
msgRef.value.msg = 'aaaaa'
mgsShallowRef.value.msg = 'bbbbb'
console.log(mgsShallowRef)
}
</script>
<template>
<div>
ref: {{msgRef}}
</div>
<div>
shallowRef: {{mgsShallowRef}}
</div>
<button @click="change">改变</button>
</template>
点击按钮改变
按照 shallowRef 的概念中 他改变是属于浅层次的响应内容
虽然打印出来的 mgsShallowRef.value 改变了 在理想状态中页面是 shallowRef: {{mgsShallowRef}} 不会发生改变的
但是实际上发生的却是 页面中的 shallowRef: {{mgsShallowRef}} 变为了 bbbbb
解答
发生了这样子的情况 肯定是抱有疑惑的 这就去看了看ref的源码
发现他调用了triggerRef这个东西
于是去官网查看了一下
发现了他确实有改变的这个效果
想要复现这个问题 只需要简单的改变一下
vue
<script setup lang="ts">
import {ref,shallowRef,triggerRef} from 'vue'
const msgRef = ref({mgs:'a'})
const mgsShallowRef = shallowRef({mgs:'b'})
cosnt change = () => {
mgsShallowRef.value.msg = 'bbbbb'
triggerRef(mgsShallowRef)
console.log(mgsShallowRef)
}
</script>
只是需要这样子调用一下 triggerRef(mgsShallowRef) 便能够复现上述的问题 造成视图的更新
所以说 triggerRef 这个会强制更新收集到的变化 所以造成了这样子的效果
探讨
想要增加一下防御型代码 shallowRef 加上triggerRef 是不是也可以做到 ref 相同的效果呢