fix(nuxt): resolve routes when navigateTo called with open (#27742)

This commit is contained in:
Daniel Roe 2024-06-20 20:26:46 +01:00
parent 8773abf15d
commit e6940dbdf5
No known key found for this signature in database
GPG Key ID: 3714AB03996F442B
3 changed files with 16 additions and 9 deletions

View File

@ -8,10 +8,10 @@ import type {
} from 'vue' } from 'vue'
import { computed, defineComponent, h, inject, onBeforeUnmount, onMounted, provide, ref, resolveComponent } from 'vue' import { computed, defineComponent, h, inject, onBeforeUnmount, onMounted, provide, ref, resolveComponent } from 'vue'
import type { RouteLocation, RouteLocationRaw, Router, RouterLink, RouterLinkProps, useLink } from '#vue-router' import type { RouteLocation, RouteLocationRaw, Router, RouterLink, RouterLinkProps, useLink } from '#vue-router'
import { hasProtocol, joinURL, parseQuery, withQuery, withTrailingSlash, withoutTrailingSlash } from 'ufo' import { hasProtocol, joinURL, parseQuery, withTrailingSlash, withoutTrailingSlash } from 'ufo'
import { preloadRouteComponents } from '../composables/preload' import { preloadRouteComponents } from '../composables/preload'
import { onNuxtReady } from '../composables/ready' import { onNuxtReady } from '../composables/ready'
import { navigateTo, useRouter } from '../composables/router' import { navigateTo, resolveRouteObject, useRouter } from '../composables/router'
import { useNuxtApp, useRuntimeConfig } from '../nuxt' import { useNuxtApp, useRuntimeConfig } from '../nuxt'
import { cancelIdleCallback, requestIdleCallback } from '../compat/idle-callback' import { cancelIdleCallback, requestIdleCallback } from '../compat/idle-callback'
@ -495,7 +495,3 @@ function isSlowConnection () {
if (cn && (cn.saveData || /2g/.test(cn.effectiveType))) { return true } if (cn && (cn.saveData || /2g/.test(cn.effectiveType))) { return true }
return false return false
} }
function resolveRouteObject (to: Exclude<RouteLocationRaw, string>) {
return withQuery(to.path || '', to.query || {}) + (to.hash ? '#' + to.hash : '')
}

View File

@ -1,6 +1,6 @@
import { getCurrentInstance, hasInjectionContext, inject, onScopeDispose } from 'vue' import { getCurrentInstance, hasInjectionContext, inject, onScopeDispose } from 'vue'
import type { Ref } from 'vue' import type { Ref } from 'vue'
import type { NavigationFailure, NavigationGuard, RouteLocationNormalized, RouteLocationPathRaw, RouteLocationRaw, Router, useRoute as _useRoute, useRouter as _useRouter } from '#vue-router' import type { NavigationFailure, NavigationGuard, RouteLocationNormalized, RouteLocationRaw, Router, useRoute as _useRoute, useRouter as _useRouter } from '#vue-router'
import { sanitizeStatusCode } from 'h3' import { sanitizeStatusCode } from 'h3'
import { hasProtocol, isScriptProtocol, joinURL, withQuery } from 'ufo' import { hasProtocol, isScriptProtocol, joinURL, withQuery } from 'ufo'
@ -120,7 +120,7 @@ export const navigateTo = (to: RouteLocationRaw | undefined | null, options?: Na
to = '/' to = '/'
} }
const toPath = typeof to === 'string' ? to : (withQuery((to as RouteLocationPathRaw).path || '/', to.query || {}) + (to.hash || '')) const toPath = typeof to === 'string' ? to : 'path' in to ? resolveRouteObject(to) : useRouter().resolve(to).href
// Early open handler // Early open handler
if (import.meta.client && options?.open) { if (import.meta.client && options?.open) {
@ -252,3 +252,10 @@ export const setPageLayout = (layout: unknown extends PageMeta['layout'] ? strin
useRoute().meta.layout = layout as Exclude<PageMeta['layout'], Ref | false> useRoute().meta.layout = layout as Exclude<PageMeta['layout'], Ref | false>
} }
} }
/**
* @internal
*/
export function resolveRouteObject (to: Exclude<RouteLocationRaw, string>) {
return withQuery(to.path || '', to.query || {}) + (to.hash || '')
}

View File

@ -1,5 +1,6 @@
import { describe, expect, it, vi } from 'vitest' import { describe, expect, it, vi } from 'vitest'
import type { RouteLocation } from 'vue-router' import type { RouteLocation, RouteLocationRaw } from 'vue-router'
import { withQuery } from 'ufo'
import type { NuxtLinkOptions, NuxtLinkProps } from '../src/app/components/nuxt-link' import type { NuxtLinkOptions, NuxtLinkProps } from '../src/app/components/nuxt-link'
import { defineNuxtLink } from '../src/app/components/nuxt-link' import { defineNuxtLink } from '../src/app/components/nuxt-link'
import { useRuntimeConfig } from '../src/app/nuxt' import { useRuntimeConfig } from '../src/app/nuxt'
@ -25,6 +26,9 @@ vi.mock('vue', async () => {
// Mocks Nuxt `useRouter()` // Mocks Nuxt `useRouter()`
vi.mock('../src/app/composables/router', () => ({ vi.mock('../src/app/composables/router', () => ({
resolveRouteObject (to: Exclude<RouteLocationRaw, string>) {
return withQuery(to.path || '', to.query || {}) + (to.hash || '')
},
useRouter: () => ({ useRouter: () => ({
resolve: (route: string | RouteLocation & { to?: string }): Partial<RouteLocation> & { href?: string } => { resolve: (route: string | RouteLocation & { to?: string }): Partial<RouteLocation> & { href?: string } => {
if (typeof route === 'string') { if (typeof route === 'string') {