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

View File

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

View File

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