From b362e0425e3683e3b8523b2664f29be375b6de82 Mon Sep 17 00:00:00 2001 From: daiwei Date: Thu, 5 Sep 2024 11:45:58 +0800 Subject: [PATCH 1/2] fix(suspense): properly update anchor if activeBranch not render to actual container --- packages/runtime-core/src/components/Suspense.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/runtime-core/src/components/Suspense.ts b/packages/runtime-core/src/components/Suspense.ts index c7562436179..85001f500cf 100644 --- a/packages/runtime-core/src/components/Suspense.ts +++ b/packages/runtime-core/src/components/Suspense.ts @@ -566,7 +566,7 @@ function createSuspenseBoundary( // (got `pendingBranch.el`). // Therefore, after the mounting of activeBranch is completed, // it is necessary to get the latest anchor. - if (parentNode(activeBranch.el!) !== suspense.hiddenContainer) { + if (parentNode(activeBranch.el!) === container) { anchor = next(activeBranch) } unmount(activeBranch, parentComponent, suspense, true) From ddf5fe3d66bfd9d82d1ba14730c54d3e52f5eb35 Mon Sep 17 00:00:00 2001 From: daiwei Date: Thu, 5 Sep 2024 13:58:33 +0800 Subject: [PATCH 2/2] test: add test case --- packages/vue/__tests__/e2e/Transition.spec.ts | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/packages/vue/__tests__/e2e/Transition.spec.ts b/packages/vue/__tests__/e2e/Transition.spec.ts index b9e9117289e..9a5375e72a2 100644 --- a/packages/vue/__tests__/e2e/Transition.spec.ts +++ b/packages/vue/__tests__/e2e/Transition.spec.ts @@ -1993,6 +1993,66 @@ describe('e2e: Transition', () => { }, E2E_TIMEOUT, ) + + // #11806 + test( + 'switch between Async and Sync child when transition is not finished', + async () => { + await page().evaluate(() => { + const { createApp, shallowRef, h, nextTick } = (window as any).Vue + createApp({ + template: ` +
+ + + + + +
+ + `, + setup: () => { + const view = shallowRef('SyncB') + const click = async () => { + view.value = 'SyncA' + await nextTick() + view.value = 'AsyncB' + await nextTick() + view.value = 'SyncB' + } + return { view, click } + }, + components: { + SyncA: { + setup() { + return () => h('div', 'SyncA') + }, + }, + AsyncB: { + async setup() { + await nextTick() + return () => h('div', 'AsyncB') + }, + }, + SyncB: { + setup() { + return () => h('div', 'SyncB') + }, + }, + }, + }).mount('#app') + }) + + expect(await html('#container')).toBe('
SyncB
') + + await click('#toggleBtn') + await nextFrame() + await transitionFinish() + await transitionFinish() + expect(await html('#container')).toBe('
SyncB
') + }, + E2E_TIMEOUT, + ) }) describe('transition with Teleport', () => {