Skip to content

Commit b700328

Browse files
authored
fix(Suspense): properly get anchor when mount fallback vnode (#9770)
close #9769
1 parent 6784f0b commit b700328

File tree

2 files changed

+68
-1
lines changed

2 files changed

+68
-1
lines changed

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

+66
Original file line numberDiff line numberDiff line change
@@ -1185,6 +1185,72 @@ describe('Suspense', () => {
11851185
expect(calls).toEqual([`one mounted`, `one unmounted`, `two mounted`])
11861186
})
11871187

1188+
test('mount the fallback content is in the correct position', async () => {
1189+
const makeComp = (name: string, delay = 0) =>
1190+
defineAsyncComponent(
1191+
{
1192+
setup() {
1193+
return () => h('div', [name])
1194+
}
1195+
},
1196+
delay
1197+
)
1198+
1199+
const One = makeComp('one')
1200+
const Two = makeComp('two', 20)
1201+
1202+
const view = shallowRef(One)
1203+
1204+
const Comp = {
1205+
setup() {
1206+
return () =>
1207+
h('div', [
1208+
h(
1209+
Suspense,
1210+
{
1211+
timeout: 10
1212+
},
1213+
{
1214+
default: h(view.value),
1215+
fallback: h('div', 'fallback')
1216+
}
1217+
),
1218+
h('div', 'three')
1219+
])
1220+
}
1221+
}
1222+
1223+
const root = nodeOps.createElement('div')
1224+
render(h(Comp), root)
1225+
expect(serializeInner(root)).toBe(
1226+
`<div><div>fallback</div><div>three</div></div>`
1227+
)
1228+
1229+
await deps[0]
1230+
await nextTick()
1231+
expect(serializeInner(root)).toBe(
1232+
`<div><div>one</div><div>three</div></div>`
1233+
)
1234+
1235+
view.value = Two
1236+
await nextTick()
1237+
expect(serializeInner(root)).toBe(
1238+
`<div><div>one</div><div>three</div></div>`
1239+
)
1240+
1241+
await new Promise(r => setTimeout(r, 10))
1242+
await nextTick()
1243+
expect(serializeInner(root)).toBe(
1244+
`<div><div>fallback</div><div>three</div></div>`
1245+
)
1246+
1247+
await deps[1]
1248+
await nextTick()
1249+
expect(serializeInner(root)).toBe(
1250+
`<div><div>two</div><div>three</div></div>`
1251+
)
1252+
})
1253+
11881254
// #2214
11891255
// Since suspense renders its own root like a component, it should not patch
11901256
// its content in optimized mode.

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,7 @@ function createSuspenseBoundary(
582582
// invoke @fallback event
583583
triggerEvent(vnode, 'onFallback')
584584

585+
const anchor = next(activeBranch!)
585586
const mountFallback = () => {
586587
if (!suspense.isInFallback) {
587588
return
@@ -591,7 +592,7 @@ function createSuspenseBoundary(
591592
null,
592593
fallbackVNode,
593594
container,
594-
next(activeBranch!),
595+
anchor,
595596
parentComponent,
596597
null, // fallback tree will not have suspense context
597598
isSVG,

0 commit comments

Comments
 (0)