From 083f90b719e0af6a60bc34e8ef347db422fc2db5 Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Mon, 31 Jan 2022 18:58:19 +0000 Subject: [PATCH] refactor: extract `` from `` (#3011) --- .../3.docs/2.directory-structure/15.app.md | 4 +- packages/nuxt3/src/pages/runtime/app.vue | 4 +- packages/nuxt3/src/pages/runtime/layout.ts | 27 ++++++++---- packages/nuxt3/src/pages/runtime/page.ts | 44 +++---------------- packages/nuxt3/src/pages/runtime/utils.ts | 15 +++++++ 5 files changed, 45 insertions(+), 49 deletions(-) create mode 100644 packages/nuxt3/src/pages/runtime/utils.ts diff --git a/docs/content/3.docs/2.directory-structure/15.app.md b/docs/content/3.docs/2.directory-structure/15.app.md index 82671e9b7c..d8761f9114 100644 --- a/docs/content/3.docs/2.directory-structure/15.app.md +++ b/docs/content/3.docs/2.directory-structure/15.app.md @@ -25,7 +25,9 @@ If you have a [`pages/`](/docs/directory-structure/pages) directory, to display ```vue [app.vue] ``` diff --git a/packages/nuxt3/src/pages/runtime/app.vue b/packages/nuxt3/src/pages/runtime/app.vue index 8f62b8bf92..f8eacfa737 100644 --- a/packages/nuxt3/src/pages/runtime/app.vue +++ b/packages/nuxt3/src/pages/runtime/app.vue @@ -1,3 +1,5 @@ diff --git a/packages/nuxt3/src/pages/runtime/layout.ts b/packages/nuxt3/src/pages/runtime/layout.ts index 419e682822..4f4781b55a 100644 --- a/packages/nuxt3/src/pages/runtime/layout.ts +++ b/packages/nuxt3/src/pages/runtime/layout.ts @@ -1,24 +1,33 @@ -import { defineComponent, h, Ref } from 'vue' +import { defineComponent, isRef, Ref, Transition } from 'vue' +import { useRoute } from 'vue-router' +import { wrapIf } from './utils' // @ts-ignore import layouts from '#build/layouts' +const defaultLayoutTransition = { name: 'layout', mode: 'out-in' } + export default defineComponent({ props: { name: { type: [String, Boolean, Object] as unknown as () => string | false | Ref, - default: 'default' + default: null } }, setup (props, context) { + const route = useRoute() + return () => { - const layout = (props.name && typeof props.name === 'object' ? props.name.value : props.name) ?? 'default' - if (!layouts[layout]) { - if (process.dev && layout && layout !== 'default') { - console.warn(`Invalid layout \`${layout}\` selected.`) - } - return context.slots.default() + const layout = (isRef(props.name) ? props.name.value : props.name) ?? route.meta.layout as string ?? 'default' + + const hasLayout = layout && layout in layouts + if (process.dev && layout && !hasLayout && layout !== 'default') { + console.warn(`Invalid layout \`${layout}\` selected.`) } - return h(layouts[layout], props, context.slots) + + // We avoid rendering layout transition if there is no layout to render + return wrapIf(Transition, hasLayout && (route.meta.layoutTransition ?? defaultLayoutTransition), + wrapIf(layouts[layout], hasLayout, context.slots) + ).default() } } }) diff --git a/packages/nuxt3/src/pages/runtime/page.ts b/packages/nuxt3/src/pages/runtime/page.ts index 4dad687375..c1b1f8116e 100644 --- a/packages/nuxt3/src/pages/runtime/page.ts +++ b/packages/nuxt3/src/pages/runtime/page.ts @@ -1,59 +1,27 @@ -import { Component, defineComponent, KeepAlive, h, Suspense, Transition } from 'vue' -import { RouterView, useRoute } from 'vue-router' -import NuxtLayout from './layout' +import { defineComponent, h, Suspense, Transition } from 'vue' +import { RouterView } from 'vue-router' +import { wrapIf, wrapInKeepAlive } from './utils' import { useNuxtApp } from '#app' -// @ts-ignore -import layouts from '#build/layouts' type InstanceOf = T extends new (...args: any[]) => infer R ? R : never type RouterViewSlotProps = Parameters['$slots']['default']>[0] export default defineComponent({ name: 'NuxtPage', - props: { - layout: { - type: String, - default: null - } - }, - setup (props) { + setup () { const nuxtApp = useNuxtApp() - const route = useRoute() return () => { - // We avoid rendering layout transition if there is no layout to render - const hasLayout = props.layout ?? route.meta.layout ?? 'default' in layouts - return h(RouterView, {}, { - default: ({ Component }: RouterViewSlotProps) => Component && - wrapIf(Transition, hasLayout && (route.meta.layoutTransition ?? defaultLayoutTransition), - wrapIf(NuxtLayout, hasLayout && { name: props.layout ?? route.meta.layout }, + default: ({ Component, route }: RouterViewSlotProps) => Component && wrapIf(Transition, route.meta.pageTransition ?? defaultPageTransition, wrapInKeepAlive(route.meta.keepalive, h(Suspense, { onPending: () => nuxtApp.callHook('page:start', Component), onResolve: () => nuxtApp.callHook('page:finish', Component) - }, { default: () => h(Component) }) - ) - ) - )).default() + }, { default: () => h(Component) }))).default() }) } } }) -const Fragment = { - setup (props, { slots }) { - return () => slots.default() - } -} - -const wrapIf = (component: Component, props: any, slots: any) => { - return { default: () => props ? h(component, props === true ? {} : props, slots) : h(Fragment, {}, slots) } -} - -const wrapInKeepAlive = (props: any, children: any) => { - return { default: () => process.client && props ? h(KeepAlive, props === true ? {} : props, children) : children } -} - -const defaultLayoutTransition = { name: 'layout', mode: 'out-in' } const defaultPageTransition = { name: 'page', mode: 'out-in' } diff --git a/packages/nuxt3/src/pages/runtime/utils.ts b/packages/nuxt3/src/pages/runtime/utils.ts new file mode 100644 index 0000000000..3a163e7573 --- /dev/null +++ b/packages/nuxt3/src/pages/runtime/utils.ts @@ -0,0 +1,15 @@ +import { Component, KeepAlive, h } from 'vue' + +const Fragment = { + setup (_props, { slots }) { + return () => slots.default() + } +} + +export const wrapIf = (component: Component, props: any, slots: any) => { + return { default: () => props ? h(component, props === true ? {} : props, slots) : h(Fragment, {}, slots) } +} + +export const wrapInKeepAlive = (props: any, children: any) => { + return { default: () => process.client && props ? h(KeepAlive, props === true ? {} : props, children) : children } +}