Modifying something nested within a shallowReactive
does not mean the mutation won't be executed. It simply indicates that Vue is not explicitly instructed to check for variances between the model (M) and the view/template/DOM (V) immediately.
When you alter test.count1
in the same function as well, which is being watched, the component undergoes a differential update. This process focuses on detecting disparities between the model and the view, disregarding whether the property is reactive or not. If discrepancies are found, they get updated accordingly.
To distinguish between changes in nested and non-nested properties, individual functions can be created. Notice that only the view updates when there is a change in the non-nested property. At this point, the entire template is scrutinized and adjusted based on the model:
const { createApp, shallowReactive } = Vue;
createApp({
setup() {
const test = shallowReactive({
count1: 0,
nested: {
count2: 0
}
})
const add = () => {
test.count1++
}
const addWithoutUpdate = () => {
test.nested.count2++;
}
return { test, add, addWithoutUpdate }
}
}).mount('#app')
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.2.37/vue.global.prod.min.js"></script>
<div id="app">
<button @click="add">+</button>
<button @click="addWithoutUpdate">Only add to nested</button>
<div>{{ test.count1 }}</div>
<div>{{ test.nested.count2 }}</div>
</div>
In essence, shallowReactive
lacks the ability to freeze nested objects. They remain mutable, yet Vue will only perform a diff on the template when a watched item truly alters. This could involve changes at the top level of the shallow reference or any other unrelated reactive variable.