From 1bf70799ccb64d1fbeb82df7d0f354a7f12a090d Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Thu, 4 Aug 2022 10:24:32 +0100 Subject: [PATCH 1/3] fix(nuxt): make route provided to page children reactive --- packages/nuxt/src/pages/runtime/page.ts | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/packages/nuxt/src/pages/runtime/page.ts b/packages/nuxt/src/pages/runtime/page.ts index f46a34a593e..a7245cc3284 100644 --- a/packages/nuxt/src/pages/runtime/page.ts +++ b/packages/nuxt/src/pages/runtime/page.ts @@ -1,4 +1,4 @@ -import { DefineComponent, defineComponent, h, inject, provide, Suspense, Transition } from 'vue' +import { computed, DefineComponent, defineComponent, h, inject, provide, reactive, Suspense, Transition } from 'vue' import { RouteLocationNormalized, RouteLocationNormalizedLoaded, RouterView } from 'vue-router' import { generateRouteKey, RouterViewSlotProps, wrapInKeepAlive } from './utils' @@ -33,14 +33,16 @@ export default defineComponent({ default: (routeProps: RouterViewSlotProps) => { if (!routeProps.Component) { return } + const key = generateRouteKey(props.pageKey, routeProps) + return _wrapIf(Transition, routeProps.route.meta.pageTransition ?? defaultPageTransition, wrapInKeepAlive(routeProps.route.meta.keepalive, isNested && nuxtApp.isHydrating // Include route children in parent suspense - ? h(Component, { key: generateRouteKey(props.pageKey, routeProps), routeProps } as {}) + ? h(Component, { key, routeProps, pageKey: key } as {}) : h(Suspense, { onPending: () => nuxtApp.callHook('page:start', routeProps.Component), onResolve: () => nuxtApp.callHook('page:finish', routeProps.Component) - }, { default: () => h(Component, { key: generateRouteKey(props.pageKey, routeProps), routeProps } as {}) }) + }, { default: () => h(Component, { key, routeProps, pageKey: key } as {}) }) )).default() } }) @@ -56,9 +58,19 @@ export default defineComponent({ const defaultPageTransition = { name: 'page', mode: 'out-in' } const Component = defineComponent({ - props: ['routeProps'], + props: ['routeProps', 'pageKey'], setup (props) { - provide('_route', props.routeProps.route) + // Prevent reactivity when the page will be rerendered in a different suspense fork + const firstKey = props.pageKey + const firstRoute = props.routeProps.route + + // Provide a reactive route within the page + const route = {} + for (const key in props.routeProps.route) { + route[key] = computed(() => firstKey === props.pageKey ? props.routeProps.route[key] : firstRoute[key]) + } + + provide('_route', reactive(route)) return () => h(props.routeProps.Component) } }) From 74a0308df169a7a7ac2e645a2e4d3aaa8dc841b6 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Thu, 4 Aug 2022 13:14:38 +0200 Subject: [PATCH 2/3] disable eslint warning --- packages/nuxt/src/pages/runtime/page.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/nuxt/src/pages/runtime/page.ts b/packages/nuxt/src/pages/runtime/page.ts index a7245cc3284..d5dfd0d4748 100644 --- a/packages/nuxt/src/pages/runtime/page.ts +++ b/packages/nuxt/src/pages/runtime/page.ts @@ -58,6 +58,7 @@ export default defineComponent({ const defaultPageTransition = { name: 'page', mode: 'out-in' } const Component = defineComponent({ + // eslint-disable-next-line vue/require-prop-types props: ['routeProps', 'pageKey'], setup (props) { // Prevent reactivity when the page will be rerendered in a different suspense fork From 28cd6073ecb82e0911b6b538a52c67a12b087ea2 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Thu, 4 Aug 2022 13:29:43 +0200 Subject: [PATCH 3/3] small refactor --- packages/nuxt/src/pages/runtime/page.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/nuxt/src/pages/runtime/page.ts b/packages/nuxt/src/pages/runtime/page.ts index d5dfd0d4748..d1e22f797d2 100644 --- a/packages/nuxt/src/pages/runtime/page.ts +++ b/packages/nuxt/src/pages/runtime/page.ts @@ -62,13 +62,13 @@ const Component = defineComponent({ props: ['routeProps', 'pageKey'], setup (props) { // Prevent reactivity when the page will be rerendered in a different suspense fork - const firstKey = props.pageKey - const firstRoute = props.routeProps.route + const previousKey = props.pageKey + const previousRoute = props.routeProps.route // Provide a reactive route within the page const route = {} for (const key in props.routeProps.route) { - route[key] = computed(() => firstKey === props.pageKey ? props.routeProps.route[key] : firstRoute[key]) + route[key] = computed(() => previousKey === props.pageKey ? props.routeProps.route[key] : previousRoute[key]) } provide('_route', reactive(route))