fix(fragment): perform direct remove when removing fragments

This avoids trying to grab .el from hoisted child nodes (which can
be created by another instance), and also skips transition check
since fragment children cannot have transitions.
This commit is contained in:
Evan You 2019-12-22 16:15:16 -05:00
parent 47a6a84631
commit 2fdb499bd9

View File

@ -1573,10 +1573,14 @@ export function createRenderer<
} }
function remove(vnode: HostVNode) { function remove(vnode: HostVNode) {
const { type, el, anchor, children, transition } = vnode const { type, el, anchor, transition } = vnode
if (type === Fragment) {
removeFragment(el!, anchor!)
return
}
const performRemove = () => { const performRemove = () => {
hostRemove(el!) hostRemove(el!)
if (anchor != null) hostRemove(anchor)
if ( if (
transition != null && transition != null &&
!transition.persisted && !transition.persisted &&
@ -1585,11 +1589,7 @@ export function createRenderer<
transition.afterLeave() transition.afterLeave()
} }
} }
if (type === Fragment) {
performRemove()
removeChildren(children as HostVNode[])
return
}
if ( if (
vnode.shapeFlag & ShapeFlags.ELEMENT && vnode.shapeFlag & ShapeFlags.ELEMENT &&
transition != null && transition != null &&
@ -1607,10 +1607,16 @@ export function createRenderer<
} }
} }
function removeChildren(children: HostVNode[]) { function removeFragment(cur: HostNode, end: HostNode) {
for (let i = 0; i < children.length; i++) { // For fragments, directly remove all contained DOM nodes.
remove(children[i]) // (fragment child nodes cannot have transition)
let next
while (cur !== end) {
next = hostNextSibling(cur)!
hostRemove(cur)
cur = next
} }
hostRemove(end)
} }
function unmountComponent( function unmountComponent(