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()