mirror of
https://github.com/nuxt/nuxt.git
synced 2025-01-18 17:35:57 +00:00
fix(nuxt): render client page directly when not hydrating (#30061)
This commit is contained in:
parent
0d263a39b7
commit
374967ba10
@ -1,6 +1,7 @@
|
|||||||
import { defineAsyncComponent, defineComponent, h } from 'vue'
|
import { defineAsyncComponent, defineComponent, h } from 'vue'
|
||||||
import type { AsyncComponentLoader } from 'vue'
|
import type { AsyncComponentLoader } from 'vue'
|
||||||
import ClientOnly from '#app/components/client-only'
|
import ClientOnly from '#app/components/client-only'
|
||||||
|
import { useNuxtApp } from '#app/nuxt'
|
||||||
|
|
||||||
/* @__NO_SIDE_EFFECTS__ */
|
/* @__NO_SIDE_EFFECTS__ */
|
||||||
export const createClientPage = (loader: AsyncComponentLoader) => {
|
export const createClientPage = (loader: AsyncComponentLoader) => {
|
||||||
@ -15,11 +16,15 @@ export const createClientPage = (loader: AsyncComponentLoader) => {
|
|||||||
return defineComponent({
|
return defineComponent({
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
setup (_, { attrs }) {
|
setup (_, { attrs }) {
|
||||||
return () => h('div', [
|
const nuxtApp = useNuxtApp()
|
||||||
h(ClientOnly, undefined, {
|
if (import.meta.server || nuxtApp.isHydrating) {
|
||||||
default: () => h(page, attrs),
|
return () => h('div', [
|
||||||
}),
|
h(ClientOnly, undefined, {
|
||||||
])
|
default: () => h(page, attrs),
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
return () => h(page, attrs)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
import { describe, expect, it } from 'vitest'
|
import { describe, expect, it } from 'vitest'
|
||||||
import type { ComponentOptions } from 'vue'
|
import type { ComponentOptions } from 'vue'
|
||||||
import { defineComponent, h, toDisplayString, useAttrs } from 'vue'
|
import { Suspense, defineComponent, h, toDisplayString, useAttrs } from 'vue'
|
||||||
import { mountSuspended } from '@nuxt/test-utils/runtime'
|
import { mountSuspended } from '@nuxt/test-utils/runtime'
|
||||||
|
import { flushPromises, mount } from '@vue/test-utils'
|
||||||
import { createClientOnly } from '../../packages/nuxt/src/app/components/client-only'
|
import { createClientOnly } from '../../packages/nuxt/src/app/components/client-only'
|
||||||
|
import { createClientPage } from '../../packages/nuxt/dist/components/runtime/client-component'
|
||||||
|
|
||||||
const Client = defineComponent({
|
const Client = defineComponent({
|
||||||
name: 'TestClient',
|
name: 'TestClient',
|
||||||
@ -27,3 +29,39 @@ describe('createClient attribute inheritance', () => {
|
|||||||
`)
|
`)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('client page', () => {
|
||||||
|
it('Should be suspensed when out of hydration', async () => {
|
||||||
|
let resolve
|
||||||
|
const promise = new Promise((_resolve) => {
|
||||||
|
resolve = _resolve
|
||||||
|
})
|
||||||
|
|
||||||
|
const comp = defineComponent({
|
||||||
|
async setup () {
|
||||||
|
await promise
|
||||||
|
return () => h('div', { id: 'async' }, 'async resolved')
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const wrapper = mount({
|
||||||
|
setup () {
|
||||||
|
return () => h('div', {}, [
|
||||||
|
h(Suspense, {}, {
|
||||||
|
default: () => h(createClientPage(() => Promise.resolve(comp)), {}),
|
||||||
|
fallback: () => h('div', { id: 'fallback' }, 'loading'),
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
await flushPromises()
|
||||||
|
expect(wrapper.find('#fallback').exists()).toBe(true)
|
||||||
|
expect(wrapper.find('#async').exists()).toBe(false)
|
||||||
|
|
||||||
|
resolve!()
|
||||||
|
await flushPromises()
|
||||||
|
expect(wrapper.find('#async').exists()).toBe(true)
|
||||||
|
expect(wrapper.find('#fallback').exists()).toBe(false)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user