feat(nuxt): add isolate page meta

This commit is contained in:
Romain Hamel 2024-10-10 00:05:41 +02:00
parent 7f12ed46e4
commit 9d5b2bd691
7 changed files with 44 additions and 1 deletions

View File

@ -38,6 +38,7 @@ interface PageMeta {
key?: false | string | ((route: RouteLocationNormalizedLoaded) => string)
keepalive?: boolean | KeepAliveProps
layout?: false | LayoutKey | Ref<LayoutKey> | ComputedRef<LayoutKey>
isolate?: boolean
middleware?: MiddlewareKey | NavigationGuard | Array<MiddlewareKey | NavigationGuard>
scrollToTop?: boolean | ((to: RouteLocationNormalizedLoaded, from: RouteLocationNormalizedLoaded) => boolean)
[key: string]: unknown
@ -88,6 +89,11 @@ interface PageMeta {
Set `key` value when you need more control over when the `<NuxtPage>` component is re-rendered.
**`isolate`**
- Type: boolean
Set to `true` when you do not want the page to inherit from your `app.vue`.
**`layout`**
- **Type**: `false` | `LayoutKey` | `Ref<LayoutKey>` | `ComputedRef<LayoutKey>`

View File

@ -13,6 +13,7 @@
:is="SingleRenderer"
v-else-if="SingleRenderer"
/>
<NuxtPage v-else-if="route?.meta?.isolate" />
<AppComponent v-else />
</Suspense>
</template>
@ -43,8 +44,9 @@ const url = import.meta.server ? nuxtApp.ssrContext.url : window.location.pathna
const SingleRenderer = import.meta.test && import.meta.dev && import.meta.server && url.startsWith('/__nuxt_component_test__/') && defineAsyncComponent(() => import('#build/test-component-wrapper.mjs')
.then(r => r.default(import.meta.server ? url : window.location.href)))
const route = useRoute()
// Inject default route (outside of pages) as active route
provide(PageRouteSymbol, useRoute())
provide(PageRouteSymbol, route)
// vue:setup hook
const results = nuxtApp.hooks.callHookWith(hooks => hooks.map(hook => hook()), 'vue:setup')

View File

@ -44,6 +44,9 @@ export interface PageMeta {
props?: RouteRecordRaw['props']
/** Set to `false` to avoid scrolling to top on page navigations */
scrollToTop?: boolean | ((to: RouteLocationNormalizedLoaded, from: RouteLocationNormalizedLoaded) => boolean)
/** Set to `true` to render this page without inheriting from `app.vue` */
isolate?: boolean
}
declare module 'vue-router' {

View File

@ -625,6 +625,13 @@ describe('pages', () => {
const html = await $fetch('/prerender/test')
expect(html).toContain('should be prerendered: true')
})
it('should render pages with meta.isolate independently', async () => {
expect(await $fetch('/not-isolated')).toContain('Nuxt App')
const html = await $fetch('/isolated')
expect(html).not.toContain('Nuxt App')
expect(html).toContain('isolated')
})
})
describe('nuxt composables', () => {

6
test/fixtures/basic/app.vue vendored Normal file
View File

@ -0,0 +1,6 @@
<template>
<NuxtLayout>
<p>Nuxt App</p>
<NuxtPage />
</NuxtLayout>
</template>

10
test/fixtures/basic/pages/isolated.vue vendored Normal file
View File

@ -0,0 +1,10 @@
<script setup lang="ts">
definePageMeta({
isolate: true,
layout: false,
})
</script>
<template>
<div> isolated </div>
</template>

View File

@ -0,0 +1,9 @@
<script setup lang="ts">
definePageMeta({
layout: false,
})
</script>
<template>
<div> not isolated </div>
</template>