Skip to content
This repository has been archived by the owner on Apr 6, 2023. It is now read-only.

fix(nuxt): separate routes for different suspense forks #6275

Merged
merged 3 commits into from
Aug 2, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions packages/nuxt/src/app/components/nuxt-root.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@
</template>

<script setup>
import { defineAsyncComponent, onErrorCaptured } from 'vue'
import { callWithNuxt, isNuxtError, showError, useError, useNuxtApp } from '#app'
import { defineAsyncComponent, onErrorCaptured, provide } from 'vue'
import { callWithNuxt, isNuxtError, showError, useError, useRoute, useNuxtApp } from '#app'

const ErrorComponent = defineAsyncComponent(() => import('#build/error-component.mjs'))

const nuxtApp = useNuxtApp()
const onResolve = () => nuxtApp.callHook('app:suspense:resolve')

// Inject default route (outside of pages) as active route
provide('_route', useRoute())

// vue:setup hook
const results = nuxtApp.hooks.callHookWith(hooks => hooks.map(hook => hook()), 'vue:setup')
if (process.dev && results && results.some(i => i && 'then' in i)) {
Expand Down
9 changes: 7 additions & 2 deletions packages/nuxt/src/app/composables/router.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { getCurrentInstance, inject } from 'vue'
import type { Router, RouteLocationNormalizedLoaded, NavigationGuard, RouteLocationNormalized, RouteLocationRaw, NavigationFailure } from 'vue-router'
import { sendRedirect } from 'h3'
import { joinURL } from 'ufo'
Expand All @@ -8,11 +9,15 @@ export const useRouter = () => {
}

export const useRoute = () => {
return useNuxtApp()._route as RouteLocationNormalizedLoaded
if (getCurrentInstance()) {
return inject<RouteLocationNormalizedLoaded>('_route', useNuxtApp()._route)
}
return useNuxtApp()._route
}

/** @deprecated Use `useRoute` instead. */
export const useActiveRoute = () => {
return useNuxtApp()._activeRoute as RouteLocationNormalizedLoaded
return useNuxtApp()._route as RouteLocationNormalizedLoaded
}

export interface RouteMiddleware {
Expand Down
33 changes: 22 additions & 11 deletions packages/nuxt/src/pages/runtime/page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,28 @@ export default defineComponent({

return () => {
return h(RouterView, { name: props.name, route: props.route, ...attrs }, {
default: (routeProps: RouterViewSlotProps) => routeProps.Component &&
_wrapIf(Transition, routeProps.route.meta.pageTransition ?? defaultPageTransition,
wrapInKeepAlive(routeProps.route.meta.keepalive,
isNested && nuxtApp.isHydrating
// Include route children in parent suspense
? h(routeProps.Component, { key: generateRouteKey(props.pageKey, routeProps) } as {})
: h(Suspense, {
onPending: () => nuxtApp.callHook('page:start', routeProps.Component),
onResolve: () => nuxtApp.callHook('page:finish', routeProps.Component)
}, { default: () => h(routeProps.Component, { key: generateRouteKey(props.pageKey, routeProps) } as {}) })
)).default()
default: (routeProps: RouterViewSlotProps) => {
if (!routeProps.Component) { return }

const Component = defineComponent({
setup () {
provide('_route', routeProps.route)
return () => h(routeProps.Component, {
key: generateRouteKey(props.pageKey, routeProps)
} as {})
}
})

return _wrapIf(Transition, routeProps.route.meta.pageTransition ?? defaultPageTransition,
wrapInKeepAlive(routeProps.route.meta.keepalive, isNested && nuxtApp.isHydrating
// Include route children in parent suspense
? h(Component)
: h(Suspense, {
onPending: () => nuxtApp.callHook('page:start', routeProps.Component),
onResolve: () => nuxtApp.callHook('page:finish', routeProps.Component)
}, { default: () => h(Component) })
)).default()
}
})
}
}
Expand Down
19 changes: 7 additions & 12 deletions packages/nuxt/src/pages/runtime/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,10 @@ export default defineNuxtPlugin(async (nuxtApp) => {
get: () => previousRoute.value
})

// https://github.com/vuejs/vue-router-next/blob/master/src/router.ts#L1192-L1200
const route = {}
for (const key in router.currentRoute.value) {
route[key] = computed(() => router.currentRoute.value[key])
}

// Allows suspending the route object until page navigation completes
const _activeRoute = shallowRef(router.resolve(initialURL) as RouteLocation)
const syncCurrentRoute = () => { _activeRoute.value = router.currentRoute.value }
// https://github.com/vuejs/vue-router-next/blob/master/src/router.ts#L1192-L1200
posva marked this conversation as resolved.
Show resolved Hide resolved
const _route = shallowRef(router.resolve(initialURL) as RouteLocation)
const syncCurrentRoute = () => { _route.value = router.currentRoute.value }
nuxtApp.hook('page:finish', syncCurrentRoute)
router.afterEach((to, from) => {
// We won't trigger suspense if the component is reused between routes
Expand All @@ -93,14 +88,14 @@ export default defineNuxtPlugin(async (nuxtApp) => {
syncCurrentRoute()
}
})

// https://github.com/vuejs/vue-router-next/blob/master/src/router.ts#L1192-L1200
const activeRoute = {}
for (const key in _activeRoute.value) {
activeRoute[key] = computed(() => _activeRoute.value[key])
const route = {}
for (const key in _route.value) {
route[key] = computed(() => _route.value[key])
}

nuxtApp._route = reactive(route)
nuxtApp._activeRoute = reactive(activeRoute)

nuxtApp._middleware = nuxtApp._middleware || {
global: [],
Expand Down