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) diff --git a/packages/vue/__tests__/e2e/Transition.spec.ts b/packages/vue/__tests__/e2e/Transition.spec.ts index 8cdda4dc63e..c0863a75991 100644 --- a/packages/vue/__tests__/e2e/Transition.spec.ts +++ b/packages/vue/__tests__/e2e/Transition.spec.ts @@ -2162,6 +2162,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', () => {