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 { defineComponent, getCurrentInstance, onErrorCaptured, ref } from 'vue'
|
||||||
import { ssrRenderAttrs, ssrRenderSlot, ssrRenderVNode } from 'vue/server-renderer'
|
import { ssrRenderAttrs, ssrRenderSlot, ssrRenderVNode } from 'vue/server-renderer'
|
||||||
|
// eslint-disable-next-line
|
||||||
|
import { isPromise } from '@vue/shared'
|
||||||
import { useState } from '../composables/state'
|
import { useState } from '../composables/state'
|
||||||
|
import { useNuxtApp } from '../nuxt'
|
||||||
import { createBuffer } from './utils'
|
import { createBuffer } from './utils'
|
||||||
|
|
||||||
const NuxtClientFallbackServer = defineComponent({
|
const NuxtClientFallbackServer = defineComponent({
|
||||||
@ -34,9 +37,10 @@ const NuxtClientFallbackServer = defineComponent({
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setup (props, ctx) {
|
async setup (props, ctx) {
|
||||||
const vm = getCurrentInstance()
|
const vm = getCurrentInstance()
|
||||||
const ssrFailed = ref(false)
|
const ssrFailed = ref(false)
|
||||||
|
const nuxtApp = useNuxtApp()
|
||||||
|
|
||||||
onErrorCaptured((err) => {
|
onErrorCaptured((err) => {
|
||||||
useState(`${props.uid}`, () => true)
|
useState(`${props.uid}`, () => true)
|
||||||
@ -53,10 +57,15 @@ const NuxtClientFallbackServer = defineComponent({
|
|||||||
ssrRenderVNode(ssrVNodes.push, defaultSlot![i], vm!)
|
ssrRenderVNode(ssrVNodes.push, defaultSlot![i], vm!)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const buffer = ssrVNodes.getBuffer()
|
||||||
|
if (buffer.hasAsync) {
|
||||||
|
await Promise.all(buffer.filter(isPromise))
|
||||||
|
}
|
||||||
|
|
||||||
return { ssrFailed, ssrVNodes }
|
return { ssrFailed, ssrVNodes }
|
||||||
} catch (ssrError) {
|
} catch (ssrError) {
|
||||||
// catch in dev
|
// catch in dev
|
||||||
useState(`${props.uid}`, () => true)
|
nuxtApp.runWithContext(() => useState(`${props.uid}`, () => true))
|
||||||
ctx.emit('ssr-error', ssrError)
|
ctx.emit('ssr-error', ssrError)
|
||||||
return { ssrFailed: true, ssrVNodes: [] }
|
return { ssrFailed: true, ssrVNodes: [] }
|
||||||
}
|
}
|
||||||
|
@ -424,7 +424,8 @@ describe('pages', () => {
|
|||||||
'clientfallback-non-stateful-setup',
|
'clientfallback-non-stateful-setup',
|
||||||
'clientfallback-non-stateful',
|
'clientfallback-non-stateful',
|
||||||
'clientfallback-stateful-setup',
|
'clientfallback-stateful-setup',
|
||||||
'clientfallback-stateful'
|
'clientfallback-stateful',
|
||||||
|
'clientfallback-async-setup'
|
||||||
]
|
]
|
||||||
const html = await $fetch('/client-fallback')
|
const html = await $fetch('/client-fallback')
|
||||||
// ensure failed components are not rendered server-side
|
// ensure failed components are not rendered server-side
|
||||||
@ -441,6 +442,9 @@ describe('pages', () => {
|
|||||||
expect(html).not.toContain('<p></p>')
|
expect(html).not.toContain('<p></p>')
|
||||||
expect(html).toContain('hi')
|
expect(html).toContain('hi')
|
||||||
|
|
||||||
|
// aysnc setup
|
||||||
|
expect(html).toContain('Work with async setup')
|
||||||
|
|
||||||
const { page, pageErrors } = await renderPage('/client-fallback')
|
const { page, pageErrors } = await renderPage('/client-fallback')
|
||||||
// ensure components reactivity once mounted
|
// ensure components reactivity once mounted
|
||||||
await page.locator('#increment-count').click()
|
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 />
|
<ClientFallbackStatefulSetup />
|
||||||
<ClientFallbackNonStatefulSetup />
|
<ClientFallbackNonStatefulSetup />
|
||||||
<ClientFallbackNonStateful />
|
<ClientFallbackNonStateful />
|
||||||
|
<ClientFallbackAsyncSetup />
|
||||||
<NuxtClientFallback keep-fallback>
|
<NuxtClientFallback keep-fallback>
|
||||||
<div>
|
<div>
|
||||||
<BreakInSetup />
|
<BreakInSetup />
|
||||||
|
Loading…
Reference in New Issue
Block a user