core icon indicating copy to clipboard operation
core copied to clipboard

fix(reactivity): fix WATCH_ARRAY v2 compat deep watching elements (fix #11872)

Open thecodewarrior opened this issue 4 months ago • 2 comments

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:

  1. 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.
  2. 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.

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

thecodewarrior avatar Oct 22 '24 22:10 thecodewarrior