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.$elshould always be the same asvm.$vnode.elmMore 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
wrapperin 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.$elshould 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.