From b700328342e17dc16b19316c2e134a26107139d2 Mon Sep 17 00:00:00 2001 From: edison Date: Fri, 8 Dec 2023 12:29:15 +0800 Subject: [PATCH] fix(Suspense): properly get anchor when mount fallback vnode (#9770) close #9769 --- .../__tests__/components/Suspense.spec.ts | 66 +++++++++++++++++++ .../runtime-core/src/components/Suspense.ts | 3 +- 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/packages/runtime-core/__tests__/components/Suspense.spec.ts b/packages/runtime-core/__tests__/components/Suspense.spec.ts index d822a992816..6fec755106a 100644 --- a/packages/runtime-core/__tests__/components/Suspense.spec.ts +++ b/packages/runtime-core/__tests__/components/Suspense.spec.ts @@ -1185,6 +1185,72 @@ describe('Suspense', () => { expect(calls).toEqual([`one mounted`, `one unmounted`, `two mounted`]) }) + test('mount the fallback content is in the correct position', async () => { + const makeComp = (name: string, delay = 0) => + defineAsyncComponent( + { + setup() { + return () => h('div', [name]) + } + }, + delay + ) + + const One = makeComp('one') + const Two = makeComp('two', 20) + + const view = shallowRef(One) + + const Comp = { + setup() { + return () => + h('div', [ + h( + Suspense, + { + timeout: 10 + }, + { + default: h(view.value), + fallback: h('div', 'fallback') + } + ), + h('div', 'three') + ]) + } + } + + const root = nodeOps.createElement('div') + render(h(Comp), root) + expect(serializeInner(root)).toBe( + `
fallback
three
` + ) + + await deps[0] + await nextTick() + expect(serializeInner(root)).toBe( + `
one
three
` + ) + + view.value = Two + await nextTick() + expect(serializeInner(root)).toBe( + `
one
three
` + ) + + await new Promise(r => setTimeout(r, 10)) + await nextTick() + expect(serializeInner(root)).toBe( + `
fallback
three
` + ) + + await deps[1] + await nextTick() + expect(serializeInner(root)).toBe( + `
two
three
` + ) + }) + // #2214 // Since suspense renders its own root like a component, it should not patch // its content in optimized mode. diff --git a/packages/runtime-core/src/components/Suspense.ts b/packages/runtime-core/src/components/Suspense.ts index 5e5521b09be..426ca0cd32c 100644 --- a/packages/runtime-core/src/components/Suspense.ts +++ b/packages/runtime-core/src/components/Suspense.ts @@ -582,6 +582,7 @@ function createSuspenseBoundary( // invoke @fallback event triggerEvent(vnode, 'onFallback') + const anchor = next(activeBranch!) const mountFallback = () => { if (!suspense.isInFallback) { return @@ -591,7 +592,7 @@ function createSuspenseBoundary( null, fallbackVNode, container, - next(activeBranch!), + anchor, parentComponent, null, // fallback tree will not have suspense context isSVG,