mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-22 05:35:13 +00:00
fix(nuxt): handle async children in ClientFallback
(#24086)
This commit is contained in:
parent
6c48f8b8e6
commit
ea3ce937e6
@ -1,6 +1,9 @@
|
||||
import { defineComponent, getCurrentInstance, onErrorCaptured, ref } from 'vue'
|
||||
import { ssrRenderAttrs, ssrRenderSlot, ssrRenderVNode } from 'vue/server-renderer'
|
||||
// eslint-disable-next-line
|
||||
import { isPromise } from '@vue/shared'
|
||||
import { useState } from '../composables/state'
|
||||
import { useNuxtApp } from '../nuxt'
|
||||
import { createBuffer } from './utils'
|
||||
|
||||
const NuxtClientFallbackServer = defineComponent({
|
||||
@ -34,9 +37,10 @@ const NuxtClientFallbackServer = defineComponent({
|
||||
return true
|
||||
}
|
||||
},
|
||||
setup (props, ctx) {
|
||||
async setup (props, ctx) {
|
||||
const vm = getCurrentInstance()
|
||||
const ssrFailed = ref(false)
|
||||
const nuxtApp = useNuxtApp()
|
||||
|
||||
onErrorCaptured((err) => {
|
||||
useState(`${props.uid}`, () => true)
|
||||
@ -53,10 +57,15 @@ const NuxtClientFallbackServer = defineComponent({
|
||||
ssrRenderVNode(ssrVNodes.push, defaultSlot![i], vm!)
|
||||
}
|
||||
|
||||
const buffer = ssrVNodes.getBuffer()
|
||||
if (buffer.hasAsync) {
|
||||
await Promise.all(buffer.filter(isPromise))
|
||||
}
|
||||
|
||||
return { ssrFailed, ssrVNodes }
|
||||
} catch (ssrError) {
|
||||
// catch in dev
|
||||
useState(`${props.uid}`, () => true)
|
||||
nuxtApp.runWithContext(() => useState(`${props.uid}`, () => true))
|
||||
ctx.emit('ssr-error', ssrError)
|
||||
return { ssrFailed: true, ssrVNodes: [] }
|
||||
}
|
||||
|
@ -424,7 +424,8 @@ describe('pages', () => {
|
||||
'clientfallback-non-stateful-setup',
|
||||
'clientfallback-non-stateful',
|
||||
'clientfallback-stateful-setup',
|
||||
'clientfallback-stateful'
|
||||
'clientfallback-stateful',
|
||||
'clientfallback-async-setup'
|
||||
]
|
||||
const html = await $fetch('/client-fallback')
|
||||
// ensure failed components are not rendered server-side
|
||||
@ -441,6 +442,9 @@ describe('pages', () => {
|
||||
expect(html).not.toContain('<p></p>')
|
||||
expect(html).toContain('hi')
|
||||
|
||||
// aysnc setup
|
||||
expect(html).toContain('Work with async setup')
|
||||
|
||||
const { page, pageErrors } = await renderPage('/client-fallback')
|
||||
// ensure components reactivity once mounted
|
||||
await page.locator('#increment-count').click()
|
||||
|
14
test/fixtures/basic/components/BreakInAsyncSetup.vue
vendored
Normal file
14
test/fixtures/basic/components/BreakInAsyncSetup.vue
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
<script setup>
|
||||
|
||||
async function getData () { }
|
||||
await getData()
|
||||
|
||||
// break server-side
|
||||
const data = window.__NUXT__
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
This breaks in server-side async setup. {{ data.serverRendered }}
|
||||
</div>
|
||||
</template>
|
11
test/fixtures/basic/components/clientFallback/AsyncSetup.vue
vendored
Normal file
11
test/fixtures/basic/components/clientFallback/AsyncSetup.vue
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
<template>
|
||||
<div>
|
||||
async setup
|
||||
<NuxtClientFallback>
|
||||
<BreakInAsyncSetup class="clientfallback-async-setup" />
|
||||
<template #fallback>
|
||||
<div>Work with async setup</div>
|
||||
</template>
|
||||
</NuxtClientFallback>
|
||||
</div>
|
||||
</template>
|
@ -38,6 +38,7 @@
|
||||
<ClientFallbackStatefulSetup />
|
||||
<ClientFallbackNonStatefulSetup />
|
||||
<ClientFallbackNonStateful />
|
||||
<ClientFallbackAsyncSetup />
|
||||
<NuxtClientFallback keep-fallback>
|
||||
<div>
|
||||
<BreakInSetup />
|
||||
|
Loading…
Reference in New Issue
Block a user