Skip to content

Commit

Permalink
fix(suspense): avoid updating anchor if activeBranch has not been ren…
Browse files Browse the repository at this point in the history
…dered to the actual container (#11818)

close #11806
  • Loading branch information
edison1105 committed Sep 5, 2024
1 parent 3634f7a commit 3c0d531
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 1 deletion.
2 changes: 1 addition & 1 deletion packages/runtime-core/src/components/Suspense.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
60 changes: 60 additions & 0 deletions packages/vue/__tests__/e2e/Transition.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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: `
<div id="container">
<Transition mode="out-in">
<Suspense>
<component :is="view"/>
</Suspense>
</Transition>
</div>
<button id="toggleBtn" @click="click">button</button>
`,
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('<div>SyncB</div>')

await click('#toggleBtn')
await nextFrame()
await transitionFinish()
await transitionFinish()
expect(await html('#container')).toBe('<div class="">SyncB</div>')
},
E2E_TIMEOUT,
)
})

describe('transition with Teleport', () => {
Expand Down

0 comments on commit 3c0d531

Please sign in to comment.