Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

thecodewarrior
Copy link

@thecodewarrior thecodewarrior commented Oct 22, 2024

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

Copy link

Size Report

Bundles

File Size Gzip Brotli
runtime-dom.global.prod.js 100 kB 38 kB 34.2 kB
vue.global.prod.js 159 kB 57.9 kB 51.4 kB

Usages

Name Size Gzip Brotli
createApp (CAPI only) 46.9 kB 18.3 kB 16.7 kB
createApp 55 kB 21.3 kB 19.4 kB
createSSRApp 59 kB 23 kB 20.9 kB
defineCustomElement 59.8 kB 22.8 kB 20.8 kB
overall 68.7 kB 26.3 kB 24 kB

Copy link

pkg-pr-new bot commented Oct 23, 2024

Open in Stackblitz

@vue/compiler-core

pnpm add https://pkg.pr.new/@vue/compiler-core@12236

@vue/compiler-dom

pnpm add https://pkg.pr.new/@vue/compiler-dom@12236

@vue/compiler-sfc

pnpm add https://pkg.pr.new/@vue/compiler-sfc@12236

@vue/compiler-ssr

pnpm add https://pkg.pr.new/@vue/compiler-ssr@12236

@vue/reactivity

pnpm add https://pkg.pr.new/@vue/reactivity@12236

@vue/runtime-core

pnpm add https://pkg.pr.new/@vue/runtime-core@12236

@vue/server-renderer

pnpm add https://pkg.pr.new/@vue/server-renderer@12236

@vue/runtime-dom

pnpm add https://pkg.pr.new/@vue/runtime-dom@12236

@vue/shared

pnpm add https://pkg.pr.new/@vue/shared@12236

vue

pnpm add https://pkg.pr.new/vue@12236

@vue/compat

pnpm add https://pkg.pr.new/@vue/compat@12236

commit: 9714124

@thecodewarrior
Copy link
Author

Re-reading the watch.ts patch, I realized that the unwrap step wouldn't unwrap arrays when isMultiSource is true. That won't be an issue however since the compat code path never creates a multi-source watch (the source parameter is only ever the single getter, never an array of sources).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Vue 2 migration build WATCH_ARRAY triggers on deep value modification
2 participants