diff --git a/packages/runtime-core/__tests__/components/Teleport.spec.ts b/packages/runtime-core/__tests__/components/Teleport.spec.ts index 5dc333ad690..79125cd04df 100644 --- a/packages/runtime-core/__tests__/components/Teleport.spec.ts +++ b/packages/runtime-core/__tests__/components/Teleport.spec.ts @@ -87,6 +87,49 @@ describe('renderer: teleport', () => { ``, ) }) + + test('update before mounted with defer', async () => { + const root = document.createElement('div') + document.body.appendChild(root) + + const show = ref(false) + const foo = ref('foo') + const Header = { + props: { foo: String }, + setup(props: any) { + return () => h('div', props.foo) + }, + } + const Footer = { + setup() { + foo.value = 'bar' + return () => h('div', 'Footer') + }, + } + createDOMApp({ + render() { + return show.value + ? [ + h( + Teleport, + { to: '#targetId', defer: true }, + h(Header, { foo: foo.value }), + ), + h(Footer), + h('div', { id: 'targetId' }), + ] + : [h('div')] + }, + }).mount(root) + + expect(root.innerHTML).toMatchInlineSnapshot(`"
"`) + + show.value = true + await nextTick() + expect(root.innerHTML).toMatchInlineSnapshot( + `"
Footer
bar
"`, + ) + }) }) function runSharedTests(deferMode: boolean) { diff --git a/packages/runtime-core/src/components/Teleport.ts b/packages/runtime-core/src/components/Teleport.ts index 5def1b2d721..fe6fa36c1ca 100644 --- a/packages/runtime-core/src/components/Teleport.ts +++ b/packages/runtime-core/src/components/Teleport.ts @@ -164,11 +164,32 @@ export const TeleportImpl = { } if (isTeleportDeferred(n2.props)) { - queuePostRenderEffect(mountToTarget, parentSuspense) + queuePostRenderEffect(() => { + mountToTarget() + n2.el!.__isMounted = true + }, parentSuspense) } else { mountToTarget() } } else { + if (isTeleportDeferred(n2.props) && !n1.el!.__isMounted) { + queuePostRenderEffect(() => { + TeleportImpl.process( + n1, + n2, + container, + anchor, + parentComponent, + parentSuspense, + namespace, + slotScopeIds, + optimized, + internals, + ) + delete n1.el!.__isMounted + }, parentSuspense) + return + } // update content n2.el = n1.el n2.targetStart = n1.targetStart