diff --git a/packages/runtime-core/__tests__/components/Teleport.spec.ts b/packages/runtime-core/__tests__/components/Teleport.spec.ts index 2307932ed6b..f6babd9263b 100644 --- a/packages/runtime-core/__tests__/components/Teleport.spec.ts +++ b/packages/runtime-core/__tests__/components/Teleport.spec.ts @@ -147,6 +147,26 @@ describe('renderer: teleport', () => { 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(`"

"`) + + render(null, root) + expect(serializeInner(target)).toBe('') + }) + test('multiple teleport with same target', () => { const target = nodeOps.createElement('div') const root = nodeOps.createElement('div') diff --git a/packages/runtime-core/src/components/Teleport.ts b/packages/runtime-core/src/components/Teleport.ts index 7bbad77fbf0..1b51a03ac94 100644 --- a/packages/runtime-core/src/components/Teleport.ts +++ b/packages/runtime-core/src/components/Teleport.ts @@ -21,7 +21,7 @@ export interface TeleportProps { 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 === '') const isTargetSVG = (target: RendererElement): boolean => @@ -218,7 +218,10 @@ export const TeleportImpl = { remove( vnode: VNode, - { r: remove, o: { remove: hostRemove } }: RendererInternals, + parentComponent: ComponentInternalInstance | null, + parentSuspense: SuspenseBoundary | null, + optimized: boolean, + { um: unmount, o: { remove: hostRemove } }: RendererInternals, doRemove: Boolean ) { const { shapeFlag, children, anchor, targetAnchor, target, props } = vnode @@ -232,7 +235,13 @@ export const TeleportImpl = { hostRemove(anchor!) if (shapeFlag & ShapeFlags.ARRAY_CHILDREN) { for (let i = 0; i < (children as VNode[]).length; i++) { - remove((children as VNode[])[i]) + unmount( + (children as VNode[])[i], + parentComponent, + parentSuspense, + true, + optimized + ) } } } diff --git a/packages/runtime-core/src/renderer.ts b/packages/runtime-core/src/renderer.ts index e12d0242fc8..d1fb8db5468 100644 --- a/packages/runtime-core/src/renderer.ts +++ b/packages/runtime-core/src/renderer.ts @@ -2108,7 +2108,14 @@ function baseCreateRenderer( } 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) {