mirror of
https://github.com/nuxt/nuxt.git
synced 2025-01-19 01:45:53 +00:00
fix(nuxt): separate routes for different suspense forks (#6275)
This commit is contained in:
parent
b12fe7eb7c
commit
c72093b1f2
@ -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)) {
|
||||
|
@ -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'
|
||||
@ -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 {
|
||||
|
@ -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
|
||||
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(routeProps.Component, { key: generateRouteKey(props.pageKey, routeProps) } as {})
|
||||
? h(Component)
|
||||
: 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: () => h(Component) })
|
||||
)).default()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -76,15 +76,9 @@ 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 }
|
||||
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
|
||||
@ -93,14 +87,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])
|
||||
|
||||
// https://github.com/vuejs/router/blob/main/packages/router/src/router.ts#L1225-L1233
|
||||
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: [],
|
||||
|
Loading…
Reference in New Issue
Block a user