From 2fdb499bd96b4d1a8a7a1964d59e8dc5dacd9d22 Mon Sep 17 00:00:00 2001 From: Evan You Date: Sun, 22 Dec 2019 16:15:16 -0500 Subject: [PATCH] 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. --- packages/runtime-core/src/renderer.ts | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/packages/runtime-core/src/renderer.ts b/packages/runtime-core/src/renderer.ts index eece7c35..0b86923e 100644 --- a/packages/runtime-core/src/renderer.ts +++ b/packages/runtime-core/src/renderer.ts @@ -1573,10 +1573,14 @@ export function createRenderer< } 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 = () => { hostRemove(el!) - if (anchor != null) hostRemove(anchor) if ( transition != null && !transition.persisted && @@ -1585,11 +1589,7 @@ export function createRenderer< transition.afterLeave() } } - if (type === Fragment) { - performRemove() - removeChildren(children as HostVNode[]) - return - } + if ( vnode.shapeFlag & ShapeFlags.ELEMENT && transition != null && @@ -1607,10 +1607,16 @@ export function createRenderer< } } - function removeChildren(children: HostVNode[]) { - for (let i = 0; i < children.length; i++) { - remove(children[i]) + function removeFragment(cur: HostNode, end: HostNode) { + // For fragments, directly remove all contained DOM nodes. + // (fragment child nodes cannot have transition) + let next + while (cur !== end) { + next = hostNextSibling(cur)! + hostRemove(cur) + cur = next } + hostRemove(end) } function unmountComponent(