Ensure Vue instance's vnode and element is up to date #4299
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fix #4284 , to recap the bug, in one sentence:
vm.$el
should always be the same asvm.$vnode.elm
More detail:
If a component changes its root element during rendering, all ancestors' placeholder root element's element should be all updated.
If one component is the root element of another component, for example
wrapper
in the test case, and wrapper's parent is updated (which triggers wrapper'supdateFromParent
),wrapper
's $vnode is not the same ascomp
's $vnode.parent. While in the initial rendering, these two vnodes are the same one.To simplify these two statements, we have to keep one invariant:
vm.$el
should always be the same asvm.$vnode.elm
. Otherwise vdom patching will mistakenly insert new dom node.If we correctly sync vnode's element when child tree's root changes its tag (1), and update vm's vnode when parent is updated(2), we can ensure $el is up to date.
I hope I made myself understood. it is quite perplexing.
I don't think this is the only way to fix the edge case. If @yyx990803 and other members have better alternatives, I'm happy to see it.