Skip to content

Commit 4162311

Browse files
authored
fix(teleport): ensure descendent component would be unmounted correctly (#6529)
fix #6347
1 parent 8f0472c commit 4162311

File tree

2 files changed

+39
-15
lines changed

2 files changed

+39
-15
lines changed

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

+25
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,31 @@ describe('renderer: teleport', () => {
172172
expect(serializeInner(target)).toBe('')
173173
})
174174

175+
// #6347
176+
test('descendent component should be unmounted when teleport is disabled and unmounted', () => {
177+
const root = nodeOps.createElement('div')
178+
179+
const CompWithHook = {
180+
render() {
181+
return [h('p'), h('p')]
182+
},
183+
beforeUnmount: vi.fn(),
184+
unmounted: vi.fn()
185+
}
186+
187+
render(
188+
h(() => [h(Teleport, { to: null, disabled: true }, h(CompWithHook))]),
189+
root
190+
)
191+
expect(CompWithHook.beforeUnmount).toBeCalledTimes(0)
192+
expect(CompWithHook.unmounted).toBeCalledTimes(0)
193+
194+
render(null, root)
195+
196+
expect(CompWithHook.beforeUnmount).toBeCalledTimes(1)
197+
expect(CompWithHook.unmounted).toBeCalledTimes(1)
198+
})
199+
175200
test('multiple teleport with same target', () => {
176201
const target = nodeOps.createElement('div')
177202
const root = nodeOps.createElement('div')

packages/runtime-core/src/components/Teleport.ts

+14-15
Original file line numberDiff line numberDiff line change
@@ -239,28 +239,27 @@ export const TeleportImpl = {
239239
parentSuspense: SuspenseBoundary | null,
240240
optimized: boolean,
241241
{ um: unmount, o: { remove: hostRemove } }: RendererInternals,
242-
doRemove: Boolean
242+
doRemove: boolean
243243
) {
244244
const { shapeFlag, children, anchor, targetAnchor, target, props } = vnode
245245

246246
if (target) {
247247
hostRemove(targetAnchor!)
248248
}
249249

250-
// an unmounted teleport should always remove its children if not disabled
251-
if (doRemove || !isTeleportDisabled(props)) {
252-
hostRemove(anchor!)
253-
if (shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
254-
for (let i = 0; i < (children as VNode[]).length; i++) {
255-
const child = (children as VNode[])[i]
256-
unmount(
257-
child,
258-
parentComponent,
259-
parentSuspense,
260-
true,
261-
!!child.dynamicChildren
262-
)
263-
}
250+
// an unmounted teleport should always unmount its children whether it's disabled or not
251+
doRemove && hostRemove(anchor!)
252+
if (shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
253+
const shouldRemove = doRemove || !isTeleportDisabled(props)
254+
for (let i = 0; i < (children as VNode[]).length; i++) {
255+
const child = (children as VNode[])[i]
256+
unmount(
257+
child,
258+
parentComponent,
259+
parentSuspense,
260+
shouldRemove,
261+
!!child.dynamicChildren
262+
)
264263
}
265264
}
266265
},

0 commit comments

Comments
 (0)