diff --git a/packages/runtime-vapor/__tests__/components/Teleport.spec.ts b/packages/runtime-vapor/__tests__/components/Teleport.spec.ts index d4282ab8a6e..5f3324e1e35 100644 --- a/packages/runtime-vapor/__tests__/components/Teleport.spec.ts +++ b/packages/runtime-vapor/__tests__/components/Teleport.spec.ts @@ -192,6 +192,7 @@ describe('renderer: VaporTeleport', () => { expect(root.innerHTML).toBe( '
root 2
', ) + await nextTick() expect(target.innerHTML).toBe('
teleported 2
') }) @@ -367,6 +368,7 @@ describe('renderer: VaporTeleport', () => { expect(root.innerHTML).toBe( '
root 2
', ) + await nextTick() expect(target.innerHTML).toBe('
teleported 2
') // reload parent again by changing disabled @@ -1255,4 +1257,41 @@ function runSharedTests(deferMode: boolean): void { expect(child.outerHTML).toBe(`
teleported
`) expect(tRefInMounted).toBe(child) }) + + test('with insertion state', async () => { + const root = document.createElement('div') + document.body.appendChild(root) + + const Comp = defineVaporComponent({ + setup() { + return template('content')() + }, + }) + + const { app, mount } = define({ + setup() { + const n0 = template('
')() + const n4 = template('
')() as any + setInsertionState(n4, null, true) + createComponent( + VaporTeleport, + { to: () => '#tt' }, + { + default: () => + createComponent(Comp, null, { + default: () => template('content')(), + }), + }, + ) + return [n0, n4] + }, + }).create() + + mount(root) + + await nextTick() + const target = document.querySelector('#tt')! + expect(target.innerHTML).toBe('content') + app.unmount() + }) } diff --git a/packages/runtime-vapor/src/components/Teleport.ts b/packages/runtime-vapor/src/components/Teleport.ts index ef3d4598c9b..0141d5595e8 100644 --- a/packages/runtime-vapor/src/components/Teleport.ts +++ b/packages/runtime-vapor/src/components/Teleport.ts @@ -161,7 +161,12 @@ export class TeleportFragment extends VaporFragment { } // mount into target container else { - if (isTeleportDeferred(this.resolvedProps!)) { + if ( + isTeleportDeferred(this.resolvedProps!) || + // force defer when the parent is not connected to the DOM, + // typically due to an early insertion caused by setInsertionState. + !this.parent!.isConnected + ) { queuePostFlushCb(mountToTarget) } else { mountToTarget()