fix(Teleport): component with multi roots should be removed when unmounted (#3157)
fix #3156
This commit is contained in:
parent
0a583d5ca2
commit
776951315d
@ -147,6 +147,26 @@ describe('renderer: teleport', () => {
|
|||||||
testUnmount({ to: null, disabled: true })
|
testUnmount({ to: null, disabled: true })
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('component with multi roots should be removed when unmounted', () => {
|
||||||
|
const target = nodeOps.createElement('div')
|
||||||
|
const root = nodeOps.createElement('div')
|
||||||
|
|
||||||
|
const Comp = {
|
||||||
|
render() {
|
||||||
|
return [h('p'), h('p')]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render(
|
||||||
|
h(() => [h(Teleport, { to: target }, h(Comp)), h('div', 'root')]),
|
||||||
|
root
|
||||||
|
)
|
||||||
|
expect(serializeInner(target)).toMatchInlineSnapshot(`"<p></p><p></p>"`)
|
||||||
|
|
||||||
|
render(null, root)
|
||||||
|
expect(serializeInner(target)).toBe('')
|
||||||
|
})
|
||||||
|
|
||||||
test('multiple teleport with same target', () => {
|
test('multiple teleport with same target', () => {
|
||||||
const target = nodeOps.createElement('div')
|
const target = nodeOps.createElement('div')
|
||||||
const root = nodeOps.createElement('div')
|
const root = nodeOps.createElement('div')
|
||||||
|
@ -21,7 +21,7 @@ export interface TeleportProps {
|
|||||||
|
|
||||||
export const isTeleport = (type: any): boolean => type.__isTeleport
|
export const isTeleport = (type: any): boolean => type.__isTeleport
|
||||||
|
|
||||||
export const isTeleportDisabled = (props: VNode['props']): boolean =>
|
const isTeleportDisabled = (props: VNode['props']): boolean =>
|
||||||
props && (props.disabled || props.disabled === '')
|
props && (props.disabled || props.disabled === '')
|
||||||
|
|
||||||
const isTargetSVG = (target: RendererElement): boolean =>
|
const isTargetSVG = (target: RendererElement): boolean =>
|
||||||
@ -218,7 +218,10 @@ export const TeleportImpl = {
|
|||||||
|
|
||||||
remove(
|
remove(
|
||||||
vnode: VNode,
|
vnode: VNode,
|
||||||
{ r: remove, o: { remove: hostRemove } }: RendererInternals,
|
parentComponent: ComponentInternalInstance | null,
|
||||||
|
parentSuspense: SuspenseBoundary | null,
|
||||||
|
optimized: boolean,
|
||||||
|
{ um: unmount, o: { remove: hostRemove } }: RendererInternals,
|
||||||
doRemove: Boolean
|
doRemove: Boolean
|
||||||
) {
|
) {
|
||||||
const { shapeFlag, children, anchor, targetAnchor, target, props } = vnode
|
const { shapeFlag, children, anchor, targetAnchor, target, props } = vnode
|
||||||
@ -232,7 +235,13 @@ export const TeleportImpl = {
|
|||||||
hostRemove(anchor!)
|
hostRemove(anchor!)
|
||||||
if (shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
|
if (shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
|
||||||
for (let i = 0; i < (children as VNode[]).length; i++) {
|
for (let i = 0; i < (children as VNode[]).length; i++) {
|
||||||
remove((children as VNode[])[i])
|
unmount(
|
||||||
|
(children as VNode[])[i],
|
||||||
|
parentComponent,
|
||||||
|
parentSuspense,
|
||||||
|
true,
|
||||||
|
optimized
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2108,7 +2108,14 @@ function baseCreateRenderer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (shapeFlag & ShapeFlags.TELEPORT) {
|
if (shapeFlag & ShapeFlags.TELEPORT) {
|
||||||
;(vnode.type as typeof TeleportImpl).remove(vnode, internals, doRemove)
|
;(vnode.type as typeof TeleportImpl).remove(
|
||||||
|
vnode,
|
||||||
|
parentComponent,
|
||||||
|
parentSuspense,
|
||||||
|
optimized,
|
||||||
|
internals,
|
||||||
|
doRemove
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doRemove) {
|
if (doRemove) {
|
||||||
|
Loading…
Reference in New Issue
Block a user