fix(nuxt): handle external links to named route objects (#27829)

This commit is contained in:
Dominic 2024-06-26 19:51:42 +10:00 committed by Daniel Roe
parent 83f3cb70de
commit 0d854d9a06
No known key found for this signature in database
GPG Key ID: CBC814C393D93268
2 changed files with 17 additions and 11 deletions

View File

@ -167,8 +167,10 @@ export function defineNuxtLink (options: NuxtLinkOptions) {
if (!to.value || isAbsoluteUrl.value) { return to.value as string } if (!to.value || isAbsoluteUrl.value) { return to.value as string }
if (isExternal.value) { if (isExternal.value) {
const path = typeof to.value === 'object' ? resolveRouteObject(to.value) : to.value const path = typeof to.value === 'object' && 'path' in to.value ? resolveRouteObject(to.value) : to.value
return resolveTrailingSlashBehavior(path, router.resolve /* will not be called */) as string // separately resolve route objects with a 'name' property and without 'path'
const href = typeof path === 'object' ? router.resolve(path).href : path
return resolveTrailingSlashBehavior(href, router.resolve /* will not be called */) as string
} }
if (typeof to.value === 'object') { if (typeof to.value === 'object') {

View File

@ -30,16 +30,15 @@ vi.mock('../src/app/composables/router', () => ({
return withQuery(to.path || '', to.query || {}) + (to.hash || '') return withQuery(to.path || '', to.query || {}) + (to.hash || '')
}, },
useRouter: () => ({ useRouter: () => ({
resolve: (route: string | RouteLocation & { to?: string }): Partial<RouteLocation> & { href?: string } => { resolve: (route: string | RouteLocation): Partial<RouteLocation> & { href: string } => {
if (typeof route === 'string') { if (typeof route === 'string') {
return { href: route, path: route } return { path: route, href: route }
} }
return route.to return {
? { href: route.to } path: route.path || `/${route.name?.toString()}`,
: {
path: route.path || `/${route.name?.toString()}` || undefined,
query: route.query || undefined, query: route.query || undefined,
hash: route.hash || undefined, hash: route.hash || undefined,
href: route.path || `/${route.name?.toString()}`,
} }
}, },
}), }),
@ -133,6 +132,10 @@ describe('nuxt-link:propsOrAttributes', () => {
expect(nuxtLink({ to: { path: '/to' }, external: true }).props.href).toBe('/to') expect(nuxtLink({ to: { path: '/to' }, external: true }).props.href).toBe('/to')
}) })
it('resolves route location object with name', () => {
expect(nuxtLink({ to: { name: 'to' }, external: true }).props.href).toBe('/to')
})
it('applies trailing slash behaviour', () => { it('applies trailing slash behaviour', () => {
expect(nuxtLink({ to: { path: '/to' }, external: true }, { trailingSlash: 'append' }).props.href).toBe('/to/') expect(nuxtLink({ to: { path: '/to' }, external: true }, { trailingSlash: 'append' }).props.href).toBe('/to/')
expect(nuxtLink({ to: '/to', external: true }, { trailingSlash: 'append' }).props.href).toBe('/to/') expect(nuxtLink({ to: '/to', external: true }, { trailingSlash: 'append' }).props.href).toBe('/to/')
@ -225,6 +228,7 @@ describe('nuxt-link:propsOrAttributes', () => {
it('forwards `to` prop', () => { it('forwards `to` prop', () => {
expect(nuxtLink({ to: '/to' }).props.to).toBe('/to') expect(nuxtLink({ to: '/to' }).props.to).toBe('/to')
expect(nuxtLink({ to: { path: '/to' } }).props.to).toEqual({ path: '/to' }) expect(nuxtLink({ to: { path: '/to' } }).props.to).toEqual({ path: '/to' })
expect(nuxtLink({ to: { name: 'to' } }).props.to).toEqual({ name: 'to' })
}) })
}) })