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: 'element' } },
|
||||||
{ type: NodeOpTypes.INSERT, targetNode: { type: 'comment' } }
|
{ 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,
|
parentSuspense: HostSuspenseBoundary | null,
|
||||||
doRemove?: boolean
|
doRemove?: boolean
|
||||||
) {
|
) {
|
||||||
const {
|
const { props, ref, children, dynamicChildren, shapeFlag } = vnode
|
||||||
el,
|
|
||||||
props,
|
|
||||||
ref,
|
|
||||||
type,
|
|
||||||
children,
|
|
||||||
dynamicChildren,
|
|
||||||
shapeFlag,
|
|
||||||
anchor,
|
|
||||||
transition
|
|
||||||
} = vnode
|
|
||||||
|
|
||||||
// unset ref
|
// unset ref
|
||||||
if (ref !== null && parentComponent !== null) {
|
if (ref !== null && parentComponent !== null) {
|
||||||
@ -1518,26 +1508,28 @@ export function createRenderer<
|
|||||||
invokeDirectiveHook(props.onVnodeBeforeUnmount, parentComponent, vnode)
|
invokeDirectiveHook(props.onVnodeBeforeUnmount, parentComponent, vnode)
|
||||||
}
|
}
|
||||||
|
|
||||||
const shouldRemoveChildren = type === Fragment && doRemove
|
|
||||||
if (dynamicChildren != null) {
|
if (dynamicChildren != null) {
|
||||||
unmountChildren(
|
// fast path for block nodes: only need to unmount dynamic children.
|
||||||
dynamicChildren,
|
unmountChildren(dynamicChildren, parentComponent, parentSuspense)
|
||||||
parentComponent,
|
|
||||||
parentSuspense,
|
|
||||||
shouldRemoveChildren
|
|
||||||
)
|
|
||||||
} else if (shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
|
} else if (shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
|
||||||
unmountChildren(
|
unmountChildren(children as HostVNode[], parentComponent, parentSuspense)
|
||||||
children as HostVNode[],
|
|
||||||
parentComponent,
|
|
||||||
parentSuspense,
|
|
||||||
shouldRemoveChildren
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doRemove) {
|
if (doRemove) {
|
||||||
const remove = () => {
|
remove(vnode)
|
||||||
hostRemove(vnode.el!)
|
}
|
||||||
|
|
||||||
|
if (props != null && props.onVnodeUnmounted != null) {
|
||||||
|
queuePostRenderEffect(() => {
|
||||||
|
invokeDirectiveHook(props.onVnodeUnmounted!, parentComponent, vnode)
|
||||||
|
}, parentSuspense)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function remove(vnode: HostVNode) {
|
||||||
|
const { type, el, anchor, children, transition } = vnode
|
||||||
|
const performRemove = () => {
|
||||||
|
hostRemove(el!)
|
||||||
if (anchor != null) hostRemove(anchor)
|
if (anchor != null) hostRemove(anchor)
|
||||||
if (
|
if (
|
||||||
transition != null &&
|
transition != null &&
|
||||||
@ -1547,27 +1539,31 @@ 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 &&
|
||||||
!transition.persisted
|
!transition.persisted
|
||||||
) {
|
) {
|
||||||
const { leave, delayLeave } = transition
|
const { leave, delayLeave } = transition
|
||||||
const performLeave = () => leave(el!, remove)
|
const performLeave = () => leave(el!, performRemove)
|
||||||
if (delayLeave) {
|
if (delayLeave) {
|
||||||
delayLeave(vnode.el!, remove, performLeave)
|
delayLeave(vnode.el!, performRemove, performLeave)
|
||||||
} else {
|
} else {
|
||||||
performLeave()
|
performLeave()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
remove()
|
performRemove()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (props != null && props.onVnodeUnmounted != null) {
|
function removeChildren(children: HostVNode[]) {
|
||||||
queuePostRenderEffect(() => {
|
for (let i = 0; i < children.length; i++) {
|
||||||
invokeDirectiveHook(props.onVnodeUnmounted!, parentComponent, vnode)
|
remove(children[i])
|
||||||
}, parentSuspense)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user