dx(suspense): warn when using async setup when not inside a Suspense boundary (#5565)

close #3649
This commit is contained in:
Thorsten Lünborg 2022-04-13 11:36:43 +02:00 committed by GitHub
parent 57ca32b096
commit 053c65bc5e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 2 deletions

View File

@ -709,7 +709,7 @@ describe('Suspense', () => {
<div v-if="errorMessage">{{ errorMessage }}</div> <div v-if="errorMessage">{{ errorMessage }}</div>
<Suspense v-else> <Suspense v-else>
<div> <div>
<Async /> <Async />
</div> </div>
<template #fallback> <template #fallback>
<div>fallback</div> <div>fallback</div>
@ -1232,4 +1232,25 @@ describe('Suspense', () => {
await nextTick() await nextTick()
expect(serializeInner(root)).toBe(`<div>parent<!----></div>`) expect(serializeInner(root)).toBe(`<div>parent<!----></div>`)
}) })
test('warn if using async setup when not in a Suspense boundary', () => {
const Child = {
name: 'Child',
async setup() {
return () => h('div', 'child')
}
}
const Parent = {
setup() {
return () => h('div', [h(Child)])
}
}
const root = nodeOps.createElement('div')
render(h(Parent), root)
expect(
`A component with async setup() must be nested in a <Suspense>`
).toHaveBeenWarned()
})
}) })

View File

@ -654,7 +654,6 @@ function setupStatefulComponent(
if (isPromise(setupResult)) { if (isPromise(setupResult)) {
setupResult.then(unsetCurrentInstance, unsetCurrentInstance) setupResult.then(unsetCurrentInstance, unsetCurrentInstance)
if (isSSR) { if (isSSR) {
// return the promise so server-renderer can wait on it // return the promise so server-renderer can wait on it
return setupResult return setupResult
@ -668,6 +667,15 @@ function setupStatefulComponent(
// async setup returned Promise. // async setup returned Promise.
// bail here and wait for re-entry. // bail here and wait for re-entry.
instance.asyncDep = setupResult instance.asyncDep = setupResult
if (__DEV__ && !instance.suspense) {
const name = Component.name ?? 'Anonymous'
warn(
`Component <${name}>: setup function returned a promise, but no ` +
`<Suspense> boundary was found in the parent component tree. ` +
`A component with async setup() must be nested in a <Suspense> ` +
`in order to be rendered.`
)
}
} else if (__DEV__) { } else if (__DEV__) {
warn( warn(
`setup() returned a Promise, but the version of Vue you are using ` + `setup() returned a Promise, but the version of Vue you are using ` +