Description
Vue version
3.5.12
Link to minimal reproduction
Steps to reproduce
Click the "test" button. The value stays false because the watcher runs. Click the "test" button again and the value changes to true because the watcher does not run.
What is expected?
The watcher should run every time the value changes.
What is actually happening?
The watcher seems to remember the value as being "true" when the value is set to "false" within its watch callback.
System Info
No response
Any additional comments?
Finally upgrading to Vue 3 and this behavior change caused a bug. In our usage, the watch callback is an edge trigger only when the value switches from true to false in some circumstances, so the watch function being called within itself was expected and handled correctly. I'm guessing this is some known trade-off for a performance optimization but wanted to call it out just in case.
The docs contain this warning:
Sync watchers do not have batching and triggers every time a reactive mutation is detected. It's ok to use them to watch simple boolean values, but avoid using them on data sources that might be synchronously mutated many times, e.g. arrays.
But that doesn't mention anything about cases where the watcher could fail to fire on a valid change.