-
-
Notifications
You must be signed in to change notification settings - Fork 8.9k
Description
Version
3.0.0-rc.4
Reproduction link
https://jsfiddle.net/skirtle/rd4y1xj3/9/
Steps to reproduce
- Make sure the developer tools are open as the example relies on a
debuggerstatement. - Click the button.
- The example should pause in the debugger at the start of the
watch. - Notice that one of the rendered values has changed in the DOM.
- Allow the code to resume running.
- Note that the other rendered value has now changed.
What is expected?
In Vue 2 the watch would run prior to rendering updates. See:
https://jsfiddle.net/skirtle/je5qdrLp/4/
What is actually happening?
The watch runs after rendering, triggering a second phase of rendering.
This appears to be because the default value for flush is 'post'. However, that seems like a strange default as a watch (when used via the options API) will generally make some kind of data change that will require further rendering updates.
In particular, consider the case where watch is used to load data asynchronously. Typically that will involve setting some sort of isLoading flag to show a load mask while the data is loading. With Vue 2 that would have triggered a single rendering update but with Vue 3 RC4 it will go through two lots of rendering.
Worse, as the watch hasn't run yet the template could be trying to render inconsistent data.
With Vue 3 the updated hook will also run twice. However, the watch handler is called between the DOM update and the call to the updated hook. This leads to a potentially confusing scenario where the DOM doesn't reflect what is in the data when updated is called. It seems counter-intuitive for a watch to run between a DOM update and the corresponding updated hook.