core
core copied to clipboard
Vue 2 migration build WATCH_ARRAY triggers on deep value modification
Vue version
3.4.38 (compat)
Link to minimal reproduction
https://stackblitz.com/edit/vitejs-vite-cpcesj?file=src%2FApp.vue
Steps to reproduce
- Create a new project with the Vue 2 migration build
- Create an array with object elements (e.g.
[{foo: 0}, {foo: 1}]
) and add a watch on it - Replace the array (
arr = [...arr]
) - Mutate the array (
arr.push({foo: 2})
) - Modify the contents of one of the elements (
arr[0].foo++
)
What is expected?
The watch should be triggered when the array is replaced or mutated, but should not be triggered when the contents of the array elements are modified (Vue 2 repro)
What is actually happening?
The watch is triggered in all three cases, on replacement, mutation, and deep modification
System Info
No response
Any additional comments?
The compat is implemented here in createWatcher, and it's implemented by doing a deep traversal of array values. The Vue 2 behavior can be reproduced by instead calling array.slice(0, 0)
there, which creates a reactive dependency on TrackOpTypes.ITERATE
. The internal shallowReadArray function may also be more appropriate to call in internal code.