]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(Teleport): component with multi roots should be removed when unmounted (#3157)
authorHcySunYang <HcySunYang@outlook.com>
Thu, 25 Mar 2021 15:02:50 +0000 (23:02 +0800)
committerGitHub <noreply@github.com>
Thu, 25 Mar 2021 15:02:50 +0000 (11:02 -0400)
fix #3156

packages/runtime-core/__tests__/components/Teleport.spec.ts
packages/runtime-core/src/components/Teleport.ts
packages/runtime-core/src/renderer.ts

index 2307932ed6b37a9a600a83a56c51cab97a6b5293..f6babd9263b8a4dfbb2ddc9f0680d4d965d9df2d 100644 (file)
@@ -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(`"<p></p><p></p>"`)
+
+    render(null, root)
+    expect(serializeInner(target)).toBe('')
+  })
+
   test('multiple teleport with same target', () => {
     const target = nodeOps.createElement('div')
     const root = nodeOps.createElement('div')
index 7bbad77fbf0a7f86528d486a2d21b89f8093f6da..1b51a03ac94e306c4ad12b415a5b49b3a1761322 100644 (file)
@@ -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
+          )
         }
       }
     }
index e12d0242fc8ccb8acd30a8debea25636a0b4ea7b..d1fb8db5468bb195073ce0db31200bef88a7869e 100644 (file)
@@ -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) {