Skip to content

Commit

Permalink
fix(suspense): display current branch if no fallback is provided
Browse files Browse the repository at this point in the history
Fix #3986
  • Loading branch information
posva committed Jun 22, 2021
1 parent ab6e927 commit 8de0372
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 2 deletions.
88 changes: 87 additions & 1 deletion packages/runtime-core/__tests__/components/Suspense.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,32 @@ describe('Suspense', () => {
expect(serializeInner(root)).toBe(`<div>async</div>`)
})

test('fallback content', async () => {
const Async = defineAsyncComponent({
render() {
return h('div', 'async')
}
})

const Comp = {
setup() {
return () =>
h(Suspense, null, {
default: h(Async),
fallback: h('div', 'fallback')
})
}
}

const root = nodeOps.createElement('div')
render(h(Comp), root)
expect(serializeInner(root)).toBe(`<div>fallback</div>`)

await Promise.all(deps)
await nextTick()
expect(serializeInner(root)).toBe(`<div>async</div>`)
})

test('emits events', async () => {
const Async = defineAsyncComponent({
render() {
Expand Down Expand Up @@ -709,7 +735,7 @@ describe('Suspense', () => {
<div v-if="errorMessage">{{ errorMessage }}</div>
<Suspense v-else>
<div>
<Async />
<Async />
</div>
<template #fallback>
<div>fallback</div>
Expand Down Expand Up @@ -983,6 +1009,66 @@ describe('Suspense', () => {
expect(serializeInner(root)).toBe(`<div>foo<div>foo nested</div></div>`)
})

test('display previous branch when timeout + no fallback slot is provided', async () => {
const toggle = ref(false)
let resolve = () => {}
let promise: Promise<void>
function createPromise() {
promise = new Promise<void>(r => {
resolve = r
})

return promise
}

const Foo = {
async setup() {
await createPromise()
return () => h('div', ['foo'])
}
}

const onPending = jest.fn()
const onFallback = jest.fn()
const onResolve = jest.fn()

const Comp = {
setup() {
return () =>
h(
Suspense,
{ timeout: 0, onPending, onFallback, onResolve },
{
default: toggle.value ? h(Foo) : 'other'
}
)
}
}

const root = nodeOps.createElement('div')
render(h(Comp), root)
expect(serializeInner(root)).toBe(`other`)
expect(onPending).toHaveBeenCalledTimes(0)
expect(onFallback).toHaveBeenCalledTimes(0)
expect(onResolve).toHaveBeenCalledTimes(1)

toggle.value = true
await nextTick()
expect(serializeInner(root)).toBe(`other`)
expect(onPending).toHaveBeenCalledTimes(1)
expect(onFallback).toHaveBeenCalledTimes(0)
expect(onResolve).toHaveBeenCalledTimes(1)

resolve()
await promise!
await nextTick()
await nextTick()
expect(serializeInner(root)).toBe(`<div>foo</div>`)
expect(onPending).toHaveBeenCalledTimes(1)
expect(onFallback).toHaveBeenCalledTimes(0)
expect(onResolve).toHaveBeenCalledTimes(2)
})

test('branch switch to 3rd branch before resolve', async () => {
const calls: string[] = []

Expand Down
4 changes: 3 additions & 1 deletion packages/runtime-core/src/components/Suspense.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
VNodeProps,
isSameVNodeType,
openBlock,
Comment,
closeBlock,
currentBlock,
createVNode
Expand Down Expand Up @@ -516,7 +517,8 @@ function createSuspenseBoundary(
},

fallback(fallbackVNode) {
if (!suspense.pendingBranch) {
// avoid displaying the fallback/emitting node if there isn't any
if (!suspense.pendingBranch || fallbackVNode.type === Comment) {
return
}

Expand Down

0 comments on commit 8de0372

Please sign in to comment.