Skip to content

Commit 878cf1a

Browse files
committed
chore: improve code
1 parent cc5dab2 commit 878cf1a

File tree

2 files changed

+110
-14
lines changed

2 files changed

+110
-14
lines changed

packages/runtime-core/__tests__/components/Suspense.spec.ts

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,98 @@ describe('Suspense', () => {
540540
expect(unmounted).not.toHaveBeenCalled()
541541
})
542542

543+
//#10042
544+
test('unmount nested suspense before parent suspense resolve', async () => {
545+
const calls: string[] = []
546+
547+
const outerToggle = ref(true)
548+
const innerToggle = ref(true)
549+
550+
const InnerA = defineAsyncComponent(
551+
{
552+
setup: () => {
553+
onUnmounted(() => {
554+
calls.push('innerA unmounted')
555+
})
556+
return () => h('div', 'innerA')
557+
},
558+
},
559+
10,
560+
)
561+
562+
const OuterA = defineAsyncComponent(
563+
{
564+
setup: () => {
565+
onUnmounted(() => {
566+
calls.push('outerA unmounted')
567+
})
568+
return () =>
569+
h(Fragment, null, [
570+
h('div', 'outerA'),
571+
innerToggle.value
572+
? h(Suspense, null, { default: h(InnerA) })
573+
: h('div', 'innerB'),
574+
])
575+
},
576+
},
577+
5,
578+
)
579+
580+
const OuterB = defineAsyncComponent(
581+
{
582+
setup: () => {
583+
onUnmounted(() => {
584+
calls.push('outerB unmounted')
585+
})
586+
return () => h('div', 'outerB')
587+
},
588+
},
589+
5,
590+
)
591+
592+
const Comp = {
593+
setup() {
594+
return () =>
595+
h(Suspense, null, {
596+
default: h(outerToggle.value ? OuterA : OuterB),
597+
fallback: h('div', 'fallback outer'),
598+
})
599+
},
600+
}
601+
602+
const root = nodeOps.createElement('div')
603+
render(h(Comp), root)
604+
expect(serializeInner(root)).toBe(`<div>fallback outer</div>`)
605+
606+
// mount outer component
607+
await Promise.all(deps)
608+
await nextTick()
609+
expect(serializeInner(root)).toBe(`<div>outerA</div><!---->`)
610+
611+
// mount inner component
612+
await Promise.all(deps)
613+
await nextTick()
614+
615+
expect(serializeInner(root)).toBe(`<div>outerA</div><div>innerA</div>`)
616+
617+
deps.length = 0
618+
619+
// toggle both outer and inner components
620+
outerToggle.value = false
621+
innerToggle.value = false
622+
623+
await Promise.all(deps)
624+
await nextTick()
625+
expect(serializeInner(root)).toBe(`<div>outerA</div><div>innerB</div>`)
626+
expect(calls).toEqual([])
627+
628+
await Promise.all(deps)
629+
await nextTick()
630+
expect(serializeInner(root)).toBe(`<div>outerB</div>`)
631+
632+
expect(calls).toEqual(['innerA unmounted', 'outerA unmounted'])
633+
})
634+
543635
// vuetifyjs/vuetify#15207
544636
test('update prop of async element before suspense resolve', async () => {
545637
let resolve: () => void

packages/runtime-core/src/renderer.ts

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,22 @@ function baseCreateRenderer(
375375
// patching & not same type, unmount old tree
376376
if (n1 && !isSameVNodeType(n1, n2)) {
377377
anchor = getNextHostNode(n1)
378+
if (parentSuspense && parentSuspense.deps > 0) {
379+
parentSuspense.preEffects.push(() => {
380+
patch(
381+
n1,
382+
n2,
383+
container,
384+
anchor,
385+
parentComponent,
386+
parentSuspense,
387+
namespace,
388+
slotScopeIds,
389+
optimized,
390+
)
391+
})
392+
return
393+
}
378394
unmount(n1, parentComponent, parentSuspense, true)
379395
n1 = null
380396
}
@@ -2134,13 +2150,7 @@ function baseCreateRenderer(
21342150
unmountComponent(vnode.component!, parentSuspense, doRemove)
21352151
} else {
21362152
if (__FEATURE_SUSPENSE__ && shapeFlag & ShapeFlags.SUSPENSE) {
2137-
if (parentSuspense && parentSuspense.deps > 0) {
2138-
parentSuspense.preEffects.push(() => {
2139-
vnode.suspense!.unmount(parentSuspense, doRemove)
2140-
})
2141-
} else {
2142-
vnode.suspense!.unmount(parentSuspense, doRemove)
2143-
}
2153+
vnode.suspense!.unmount(parentSuspense, doRemove)
21442154
return
21452155
}
21462156

@@ -2181,13 +2191,7 @@ function baseCreateRenderer(
21812191
}
21822192

21832193
if (doRemove) {
2184-
if (parentSuspense && parentSuspense.deps > 0) {
2185-
parentSuspense.preEffects.push(() => {
2186-
remove(vnode)
2187-
})
2188-
} else {
2189-
remove(vnode)
2190-
}
2194+
remove(vnode)
21912195
}
21922196
}
21932197

0 commit comments

Comments
 (0)