Skip to content

docs: fix reactivity API examples that do not match Vue 3.5 behavior - #3484

Open
yxshee wants to merge 1 commit into
vuejs:mainfrom
yxshee:fix/reactivity-api-examples
Open

yxshee wants to merge 1 commit into
vuejs:mainfrom
yxshee:fix/reactivity-api-examples

Conversation

@yxshee

@yxshee yxshee commented Oct 26, 2026

Copy link
Copy Markdown

Description of Problem

I ran the code examples on the reactivity API pages against the latest Vue release (3.5.44). Five of them do not do what the docs say.

  1. watchEffect() side effect cleanup (api/reactivity-core.md, both the onCleanup and the onWatcherCleanup example). They call doAsyncWork(newId), but newId is not defined inside a watchEffect(). It looks like it was copied from the watch() example. Running it throws ReferenceError: newId is not defined.
  2. watch() pause / resume (api/reactivity-core.md). The example is watch(() => {}) with no callback. In 3.5 that only logs a warning: "watch(fn, options?) signature has been moved to a separate API. Use watchEffect(fn, options?) instead." It also fails to type-check (Expected 2-3 arguments, but got 1).
  3. toRefs() type (api/reactivity-utilities.md). The block declares type ToRef = T extends Ref ? T : Ref<T> without the <T> parameter, so T is undefined (Cannot find name 'T'). The toRef() section on the same page already has type ToRef<T>.
  4. app.config.idPrefix (api/application.md). The example says useId() returns 'myApp:0' and 'myApp:1'. Vue 3.5.0 used : as the separator, but current 3.5 releases use -, so the real values are 'myApp-0' and 'myApp-1'.
  5. Computed debugging (guide/extras/reactivity-in-depth.md). The example says count.value++ should trigger onTrigger. Since 3.5, a computed only tracks its dependencies while it has a subscriber, so in the example as written onTrigger is never called. The core tests say the same thing ("computed won't track until it has a subscriber" in packages/reactivity/__tests__/computed.spec.ts).

Proposed Solution

  1. Use doAsyncWork(id.value) in both watchEffect() cleanup examples.
  2. Change the example to watch(source, callback), the same form the "Stopping the watcher" example right above it uses.
  3. Add the missing type parameter: type ToRef<T> = ....
  4. Change the comments to 'myApp-0' and 'myApp-1'.
  5. Add watchEffect(() => plusOne.value) before the mutation, with a short comment that onTrigger only runs while the computed has a subscriber.

Additional Information

How I checked each one, with vue@3.5.44 in Node 22 (dev build):

  1. The original watchEffect example throws ReferenceError: newId is not defined. With id.value, changing id from 1 to 2 calls cancel() for id 1 and data ends up as the result for id 2. Same result for the onWatcherCleanup version.
  2. watch(() => {}) logs the warning above. watch(source, callback) returns { stop, pause, resume }, no callback runs while paused, and none runs after stop().
  3. tsc --strict on the old line gives TS2304: Cannot find name 'T'. The new line type-checks.
  4. useId() with idPrefix = 'myApp' returns myApp-0 and myApp-1, both from renderToString and from a client createApp().mount(). The source in runtime-core/src/helpers/useId.ts joins with '-'. @vue/runtime-core@3.5.0 still used ':'.
  5. Without a subscriber, onTrack fires but onTrigger never does. After adding the watchEffect, count.value++ calls onTrigger with type: 'set', key: 'value', 0 -> 1.

I ran Prettier with the repo config on the changed files. It reports the same differences before and after this change, so I added no new ones.

- watchEffect() cleanup examples referenced an undefined `newId`
  variable; read `id.value` instead.
- The watch() pause/resume example called `watch(() => {})`, which
  only logs a warning in 3.5 because a callback is required. Use
  `watch(source, callback)` like the other examples in the section.
- The toRefs() type block declared `type ToRef` without its type
  parameter.
- useId() with `app.config.idPrefix = 'myApp'` returns 'myApp-0', not
  'myApp:0'. The separator changed after 3.5.0.
- The computed debugging example said mutating `count.value` would
  call onTrigger, but since 3.5 a computed only tracks its
  dependencies while it has a subscriber. Add a watcher to the example.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NQDmA3mwGfL83pbg9WQ6ey
@netlify

netlify Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for vuejs ready!

Name Link
🔨 Latest commit f0f9ea0
🔍 Latest deploy log https://app.netlify.com/projects/vuejs/deploys/6adf43f81038dcb3e8440b27
😎 Deploy Preview https://deploy-preview-3484--vuejs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant