fix(fragment): properly remove compiler generated fragments
This commit is contained in:
parent
6797e35703
commit
fa5390fb6f
@ -260,5 +260,9 @@ describe('renderer: fragment', () => {
|
||||
{ type: NodeOpTypes.INSERT, targetNode: { type: 'element' } },
|
||||
{ type: NodeOpTypes.INSERT, targetNode: { type: 'comment' } }
|
||||
])
|
||||
|
||||
// should properly remove nested fragments
|
||||
render(null, root)
|
||||
expect(serializeInner(root)).toBe(``)
|
||||
})
|
||||
})
|
||||
|
@ -1483,17 +1483,7 @@ export function createRenderer<
|
||||
parentSuspense: HostSuspenseBoundary | null,
|
||||
doRemove?: boolean
|
||||
) {
|
||||
const {
|
||||
el,
|
||||
props,
|
||||
ref,
|
||||
type,
|
||||
children,
|
||||
dynamicChildren,
|
||||
shapeFlag,
|
||||
anchor,
|
||||
transition
|
||||
} = vnode
|
||||
const { props, ref, children, dynamicChildren, shapeFlag } = vnode
|
||||
|
||||
// unset ref
|
||||
if (ref !== null && parentComponent !== null) {
|
||||
@ -1518,50 +1508,15 @@ export function createRenderer<
|
||||
invokeDirectiveHook(props.onVnodeBeforeUnmount, parentComponent, vnode)
|
||||
}
|
||||
|
||||
const shouldRemoveChildren = type === Fragment && doRemove
|
||||
if (dynamicChildren != null) {
|
||||
unmountChildren(
|
||||
dynamicChildren,
|
||||
parentComponent,
|
||||
parentSuspense,
|
||||
shouldRemoveChildren
|
||||
)
|
||||
// fast path for block nodes: only need to unmount dynamic children.
|
||||
unmountChildren(dynamicChildren, parentComponent, parentSuspense)
|
||||
} else if (shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
|
||||
unmountChildren(
|
||||
children as HostVNode[],
|
||||
parentComponent,
|
||||
parentSuspense,
|
||||
shouldRemoveChildren
|
||||
)
|
||||
unmountChildren(children as HostVNode[], parentComponent, parentSuspense)
|
||||
}
|
||||
|
||||
if (doRemove) {
|
||||
const remove = () => {
|
||||
hostRemove(vnode.el!)
|
||||
if (anchor != null) hostRemove(anchor)
|
||||
if (
|
||||
transition != null &&
|
||||
!transition.persisted &&
|
||||
transition.afterLeave
|
||||
) {
|
||||
transition.afterLeave()
|
||||
}
|
||||
}
|
||||
if (
|
||||
vnode.shapeFlag & ShapeFlags.ELEMENT &&
|
||||
transition != null &&
|
||||
!transition.persisted
|
||||
) {
|
||||
const { leave, delayLeave } = transition
|
||||
const performLeave = () => leave(el!, remove)
|
||||
if (delayLeave) {
|
||||
delayLeave(vnode.el!, remove, performLeave)
|
||||
} else {
|
||||
performLeave()
|
||||
}
|
||||
} else {
|
||||
remove()
|
||||
}
|
||||
remove(vnode)
|
||||
}
|
||||
|
||||
if (props != null && props.onVnodeUnmounted != null) {
|
||||
@ -1571,6 +1526,47 @@ export function createRenderer<
|
||||
}
|
||||
}
|
||||
|
||||
function remove(vnode: HostVNode) {
|
||||
const { type, el, anchor, children, transition } = vnode
|
||||
const performRemove = () => {
|
||||
hostRemove(el!)
|
||||
if (anchor != null) hostRemove(anchor)
|
||||
if (
|
||||
transition != null &&
|
||||
!transition.persisted &&
|
||||
transition.afterLeave
|
||||
) {
|
||||
transition.afterLeave()
|
||||
}
|
||||
}
|
||||
if (type === Fragment) {
|
||||
performRemove()
|
||||
removeChildren(children as HostVNode[])
|
||||
return
|
||||
}
|
||||
if (
|
||||
vnode.shapeFlag & ShapeFlags.ELEMENT &&
|
||||
transition != null &&
|
||||
!transition.persisted
|
||||
) {
|
||||
const { leave, delayLeave } = transition
|
||||
const performLeave = () => leave(el!, performRemove)
|
||||
if (delayLeave) {
|
||||
delayLeave(vnode.el!, performRemove, performLeave)
|
||||
} else {
|
||||
performLeave()
|
||||
}
|
||||
} else {
|
||||
performRemove()
|
||||
}
|
||||
}
|
||||
|
||||
function removeChildren(children: HostVNode[]) {
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
remove(children[i])
|
||||
}
|
||||
}
|
||||
|
||||
function unmountComponent(
|
||||
instance: ComponentInternalInstance,
|
||||
parentSuspense: HostSuspenseBoundary | null,
|
||||
|
Loading…
Reference in New Issue
Block a user