Skip to content

Commit 2fdb499

Browse files
committed
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.
1 parent 47a6a84 commit 2fdb499

File tree

1 file changed

+16
-10
lines changed

1 file changed

+16
-10
lines changed

packages/runtime-core/src/renderer.ts

+16-10
Original file line numberDiff line numberDiff line change
@@ -1573,10 +1573,14 @@ export function createRenderer<
15731573
}
15741574

15751575
function remove(vnode: HostVNode) {
1576-
const { type, el, anchor, children, transition } = vnode
1576+
const { type, el, anchor, transition } = vnode
1577+
if (type === Fragment) {
1578+
removeFragment(el!, anchor!)
1579+
return
1580+
}
1581+
15771582
const performRemove = () => {
15781583
hostRemove(el!)
1579-
if (anchor != null) hostRemove(anchor)
15801584
if (
15811585
transition != null &&
15821586
!transition.persisted &&
@@ -1585,11 +1589,7 @@ export function createRenderer<
15851589
transition.afterLeave()
15861590
}
15871591
}
1588-
if (type === Fragment) {
1589-
performRemove()
1590-
removeChildren(children as HostVNode[])
1591-
return
1592-
}
1592+
15931593
if (
15941594
vnode.shapeFlag & ShapeFlags.ELEMENT &&
15951595
transition != null &&
@@ -1607,10 +1607,16 @@ export function createRenderer<
16071607
}
16081608
}
16091609

1610-
function removeChildren(children: HostVNode[]) {
1611-
for (let i = 0; i < children.length; i++) {
1612-
remove(children[i])
1610+
function removeFragment(cur: HostNode, end: HostNode) {
1611+
// For fragments, directly remove all contained DOM nodes.
1612+
// (fragment child nodes cannot have transition)
1613+
let next
1614+
while (cur !== end) {
1615+
next = hostNextSibling(cur)!
1616+
hostRemove(cur)
1617+
cur = next
16131618
}
1619+
hostRemove(end)
16141620
}
16151621

16161622
function unmountComponent(

0 commit comments

Comments
 (0)