fix(suspense): avoid updating anchor if activeBranch has not been rendered to the actual container (#11818)

close #11806
This commit is contained in:
edison 2024-09-05 20:56:34 +08:00 committed by GitHub
parent 3634f7a4c1
commit 3c0d531fa7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 61 additions and 1 deletions

View File

@ -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)

View File

@ -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', () => {