Skip to content

Commit 9c382fc

Browse files
committed
test: add test case
chore: improve code chore: improve code chore: improve code chore(deps): update dependency @types/node to v18 (vuejs#9323) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> chore: improve code chore: revert code chore: improve code
1 parent c9f53cc commit 9c382fc

File tree

2 files changed

+24
-23
lines changed

2 files changed

+24
-23
lines changed

packages/runtime-core/src/components/Suspense.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,8 @@ export interface SuspenseBoundary {
379379
container: RendererElement
380380
hiddenContainer: RendererElement
381381
anchor: RendererNode | null
382-
activeBranch: (VNode & { __isUnmounted?: boolean }) | null
382+
activeBranch: VNode | null
383+
initialContent: VNode | null
383384
pendingBranch: VNode | null
384385
deps: number
385386
pendingId: number
@@ -462,6 +463,7 @@ function createSuspenseBoundary(
462463
pendingId: 0,
463464
timeout: typeof timeout === 'number' ? timeout : -1,
464465
activeBranch: null,
466+
initialContent: null,
465467
pendingBranch: null,
466468
isInFallback: true,
467469
isHydrating,
@@ -506,12 +508,13 @@ function createSuspenseBoundary(
506508
}
507509
}
508510
// this is initial anchor on mount
509-
let { anchor } = suspense
511+
let { anchor, initialContent } = suspense
510512
// unmount current active tree
511-
// #7966 if suspense is wrapped in Transition, the Transition's afterLeave may not have been
512-
// performed (this means the fallbackVNode not mounted) when suspense resolves.
513-
// so avoid unmount activeBranch again
514-
if (activeBranch && !activeBranch.__isUnmounted) {
513+
// #7966 when Suspense is wrapped in Transition, the fallback node will be mounted
514+
// in the afterLeave of Transition. This means that when Suspense is resolved,
515+
// the activeBranch is not the fallback node but the initialContent.
516+
// so avoid unmounting the activateBranch again.
517+
if (activeBranch && activeBranch !== initialContent) {
515518
// if the fallback tree was mounted, it may have been moved
516519
// as part of a parent suspense. get the latest anchor for insertion
517520
anchor = next(activeBranch)
@@ -578,6 +581,7 @@ function createSuspenseBoundary(
578581

579582
const anchor = next(activeBranch!)
580583
const mountFallback = () => {
584+
suspense.initialContent = null
581585
if (!suspense.isInFallback) {
582586
return
583587
}
@@ -599,6 +603,7 @@ function createSuspenseBoundary(
599603
const delayEnter =
600604
fallbackVNode.transition && fallbackVNode.transition.mode === 'out-in'
601605
if (delayEnter) {
606+
suspense.initialContent = activeBranch!
602607
activeBranch!.transition!.afterLeave = mountFallback
603608
}
604609
suspense.isInFallback = true
@@ -611,8 +616,6 @@ function createSuspenseBoundary(
611616
true // shouldRemove
612617
)
613618

614-
activeBranch!.__isUnmounted = true
615-
616619
if (!delayEnter) {
617620
mountFallback()
618621
}

packages/vue/__tests__/e2e/Transition.spec.ts

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1503,9 +1503,7 @@ describe('e2e: Transition', () => {
15031503
'avoid unmount activeBranch twice with Suspense (out-in mode + timeout="0")',
15041504
async () => {
15051505
const unmountSpy = vi.fn()
1506-
15071506
await page().exposeFunction('unmountSpy', unmountSpy)
1508-
15091507
await page().evaluate(() => {
15101508
const { createApp, shallowRef, h } = (window as any).Vue
15111509
const One = {
@@ -1527,19 +1525,19 @@ describe('e2e: Transition', () => {
15271525
}
15281526
createApp({
15291527
template: `
1530-
<div id="container">
1531-
<transition mode="out-in">
1532-
<suspense timeout="0">
1533-
<template #default>
1534-
<component :is="view"></component>
1535-
</template>
1536-
<template #fallback>
1537-
<div>Loading...</div>
1538-
</template>
1539-
</suspense>
1540-
</transition>
1541-
</div>
1542-
<button id="toggleBtn" @click="click">button</button>
1528+
<div id="container">
1529+
<transition mode="out-in">
1530+
<suspense timeout="0">
1531+
<template #default>
1532+
<component :is="view"></component>
1533+
</template>
1534+
<template #fallback>
1535+
<div>Loading...</div>
1536+
</template>
1537+
</suspense>
1538+
</transition>
1539+
</div>
1540+
<button id="toggleBtn" @click="click">button</button>
15431541
`,
15441542
setup: () => {
15451543
const view = shallowRef(One)

0 commit comments

Comments
 (0)