core
core copied to clipboard
fix(reactivity): fix WATCH_ARRAY v2 compat deep watching elements (fix #11872)
close #11872
This makes a minor change that brings the WATCH_ARRAY
compat behavior further in line with the Vue 2 behavior.
Currently, watching an array with WATCH_ARRAY
compat enabled will trigger the watch function on deep mutation of elements. This differs from the Vue 2 behavior, where the watch would trigger when array elements were added/removed/replaced, but not mutated.
Changes:
- Changes the WATCH_ARRAY compat to do a depth=1 traverse, meaning it will no longer create reactive dependencies on the contents of the elements.
- Removes the getter call and
isArray
+isCompatEnabled
check that was done before wrapping the getter, for a couple reasons:- The wrapped getter will be called immediately by
watch
anyway, so this pre-check is redundant. - The previous behavior of setting
options.deep = true
based on the initial value would lead to incorrect behavior if the initial value was an array but a future value wasn't.
- The wrapped getter will be called immediately by
I couldn't find a way to test this change directly, however in an internal project an identical change using patch-package is working beautifully.
Also as a proof of concept that depth=1 would work I forked the reproduction example from #11872, disabled the WATCH_ARRAY
compat, and set the watch to use deep: 1
: https://stackblitz.com/edit/vitejs-vite-qarbhv?file=src%2FApp.vue