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
debugger
statement. - 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.