fix(nuxt3): include error and pending values in asyncData state (#2130)

This commit is contained in:
Daniel Roe 2021-11-24 19:59:04 +00:00 committed by GitHub
parent f5307f9d13
commit 955fa364fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 20 additions and 18 deletions

View File

@ -5,6 +5,7 @@ import { setNuxtAppInstance } from '#app'
// Reshape payload to match key `useLazyAsyncData` expects
function proxiedState (state) {
state._asyncData = state._asyncData || {}
state._errors = state._errors || {}
return new Proxy(state, {
get (target, prop) {
if (prop === 'data') {
@ -39,7 +40,7 @@ export default (ctx, inject) => {
globalName: 'nuxt',
payload: proxiedState(process.client ? ctx.nuxtState : ctx.ssrContext.nuxt),
_asyncDataPromises: [],
isHydrating: ctx.isHMR,
isHydrating: true,
nuxt2Context: ctx
}
@ -51,6 +52,10 @@ export default (ctx, inject) => {
ctx.app.created = [ctx.app.created]
}
if (!Array.isArray(ctx.app.mounted)) {
ctx.app.mounted = [ctx.app.mounted]
}
if (process.server) {
nuxtApp.ssrContext = ctx.ssrContext
}
@ -59,6 +64,8 @@ export default (ctx, inject) => {
nuxtApp.vue2App = this
})
ctx.app.mounted.push(() => { nuxtApp.isHydrating = false })
const proxiedApp = new Proxy(nuxtApp, {
get (target, prop) {
if (prop[0] === '$') {

View File

@ -75,7 +75,7 @@ export function useAsyncData<
const asyncData = {
data: ref(nuxt.payload.data[key] ?? options.default()),
pending: ref(true),
error: ref(null)
error: ref(nuxt.payload._errors[key] ?? null)
} as AsyncData<DataT>
asyncData.refresh = (force?: boolean) => {
@ -84,7 +84,7 @@ export function useAsyncData<
return nuxt._asyncDataPromises[key]
}
asyncData.pending.value = true
// TODO: Cancel previus promise
// TODO: Cancel previous promise
// TODO: Handle immediate errors
nuxt._asyncDataPromises[key] = Promise.resolve(handler(nuxt))
.then((result) => {
@ -104,13 +104,13 @@ export function useAsyncData<
.finally(() => {
asyncData.pending.value = false
nuxt.payload.data[key] = asyncData.data.value
nuxt.payload._errors[key] = !!asyncData.error.value
delete nuxt._asyncDataPromises[key]
})
return nuxt._asyncDataPromises[key]
}
const fetchOnServer = options.server !== false && nuxt.payload.serverRendered
const clientOnly = options.server === false || !nuxt.payload.serverRendered
// Server side
if (process.server && fetchOnServer) {
@ -120,16 +120,11 @@ export function useAsyncData<
// Client side
if (process.client) {
if (fetchOnServer && nuxt.isHydrating) {
// 1. Hydration (server: true): no fetch
if (nuxt.isHydrating && fetchOnServer) {
asyncData.pending.value = false
}
} else if (instance && (nuxt.isHydrating || options.lazy)) {
// 2. Initial load (server: false): fetch on mounted
if (instance && nuxt.isHydrating && clientOnly) {
// Fetch on mounted (initial load or lazy fetch)
instance._nuxtOnBeforeMountCbs.push(asyncData.refresh)
} else if (!nuxt.isHydrating) { // Navigation
if (instance && options.lazy) {
// 3. Navigation (lazy: true): fetch on mounted
instance._nuxtOnBeforeMountCbs.push(asyncData.refresh)
} else {
@ -137,7 +132,6 @@ export function useAsyncData<
asyncData.refresh()
}
}
}
// Allow directly awaiting on asyncData
const asyncDataPromise = Promise.resolve(nuxt._asyncDataPromises[key]).then(() => asyncData) as AsyncData<DataT>

View File

@ -76,6 +76,7 @@ export function createNuxtApp (options: CreateOptions) {
payload: reactive({
data: {},
state: {},
_errors: {},
...(process.client ? window.__NUXT__ : { serverRendered: true })
}),
isHydrating: process.client,