From 75c2463b035a7d4ace3a94c325b3d31ae81f2c34 Mon Sep 17 00:00:00 2001 From: daiwei Date: Mon, 14 Oct 2024 11:14:58 +0800 Subject: [PATCH 1/3] fix(Teleport): handle deferred teleport update before mounted --- .../runtime-core/src/components/Teleport.ts | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/packages/runtime-core/src/components/Teleport.ts b/packages/runtime-core/src/components/Teleport.ts index 5def1b2d721..938a0038335 100644 --- a/packages/runtime-core/src/components/Teleport.ts +++ b/packages/runtime-core/src/components/Teleport.ts @@ -71,7 +71,7 @@ const resolveTarget = ( return targetSelector as T } } - +let isMounted = false export const TeleportImpl = { name: 'Teleport', __isTeleport: true, @@ -133,6 +133,7 @@ export const TeleportImpl = { optimized, ) } + isMounted = true } const mountToTarget = () => { @@ -169,6 +170,25 @@ export const TeleportImpl = { mountToTarget() } } else { + if (isTeleportDeferred(n2.props) && !isMounted) { + queuePostRenderEffect( + () => + TeleportImpl.process( + n1, + n2, + container, + anchor, + parentComponent, + parentSuspense, + namespace, + slotScopeIds, + optimized, + internals, + ), + parentSuspense, + ) + return + } // update content n2.el = n1.el n2.targetStart = n1.targetStart From 66d8bf80a827c9af36a9547727d21911f5674384 Mon Sep 17 00:00:00 2001 From: daiwei Date: Mon, 14 Oct 2024 14:16:43 +0800 Subject: [PATCH 2/3] chore: update --- .../__tests__/components/Teleport.spec.ts | 44 +++++++++++++++++++ .../runtime-core/src/components/Teleport.ts | 41 ++++++++--------- 2 files changed, 65 insertions(+), 20 deletions(-) diff --git a/packages/runtime-core/__tests__/components/Teleport.spec.ts b/packages/runtime-core/__tests__/components/Teleport.spec.ts index 5dc333ad690..d7bde999b96 100644 --- a/packages/runtime-core/__tests__/components/Teleport.spec.ts +++ b/packages/runtime-core/__tests__/components/Teleport.spec.ts @@ -87,6 +87,50 @@ 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) { + foo.value = 'bar' + 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 938a0038335..fe6fa36c1ca 100644 --- a/packages/runtime-core/src/components/Teleport.ts +++ b/packages/runtime-core/src/components/Teleport.ts @@ -71,7 +71,7 @@ const resolveTarget = ( return targetSelector as T } } -let isMounted = false + export const TeleportImpl = { name: 'Teleport', __isTeleport: true, @@ -133,7 +133,6 @@ export const TeleportImpl = { optimized, ) } - isMounted = true } const mountToTarget = () => { @@ -165,28 +164,30 @@ export const TeleportImpl = { } if (isTeleportDeferred(n2.props)) { - queuePostRenderEffect(mountToTarget, parentSuspense) + queuePostRenderEffect(() => { + mountToTarget() + n2.el!.__isMounted = true + }, parentSuspense) } else { mountToTarget() } } else { - if (isTeleportDeferred(n2.props) && !isMounted) { - queuePostRenderEffect( - () => - TeleportImpl.process( - n1, - n2, - container, - anchor, - parentComponent, - parentSuspense, - namespace, - slotScopeIds, - optimized, - internals, - ), - parentSuspense, - ) + 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 From 30eaac7925112310c1f7c8f8bf52db73c55824c1 Mon Sep 17 00:00:00 2001 From: daiwei Date: Mon, 14 Oct 2024 14:17:20 +0800 Subject: [PATCH 3/3] chore: update --- packages/runtime-core/__tests__/components/Teleport.spec.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/runtime-core/__tests__/components/Teleport.spec.ts b/packages/runtime-core/__tests__/components/Teleport.spec.ts index d7bde999b96..79125cd04df 100644 --- a/packages/runtime-core/__tests__/components/Teleport.spec.ts +++ b/packages/runtime-core/__tests__/components/Teleport.spec.ts @@ -97,7 +97,6 @@ describe('renderer: teleport', () => { const Header = { props: { foo: String }, setup(props: any) { - foo.value = 'bar' return () => h('div', props.foo) }, }