mirror of
https://github.com/nuxt/nuxt.git
synced 2025-01-18 09:25:54 +00:00
fix(nuxt): don't use <RouterLink>
for links starting with #
(#30190)
This commit is contained in:
parent
1f09e69335
commit
03f0d1aec3
@ -18,6 +18,8 @@ import { cancelIdleCallback, requestIdleCallback } from '../compat/idle-callback
|
|||||||
// @ts-expect-error virtual file
|
// @ts-expect-error virtual file
|
||||||
import { nuxtLinkDefaults } from '#build/nuxt.config.mjs'
|
import { nuxtLinkDefaults } from '#build/nuxt.config.mjs'
|
||||||
|
|
||||||
|
import { hashMode } from '#build/router.options'
|
||||||
|
|
||||||
const firstNonUndefined = <T> (...args: (T | undefined)[]) => args.find(arg => arg !== undefined)
|
const firstNonUndefined = <T> (...args: (T | undefined)[]) => args.find(arg => arg !== undefined)
|
||||||
|
|
||||||
const NuxtLinkDevKeySymbol: InjectionKey<boolean> = Symbol('nuxt-link-dev-key')
|
const NuxtLinkDevKeySymbol: InjectionKey<boolean> = Symbol('nuxt-link-dev-key')
|
||||||
@ -110,6 +112,10 @@ export function defineNuxtLink (options: NuxtLinkOptions) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isHashLinkWithoutHashMode (link: unknown): boolean {
|
||||||
|
return !hashMode && typeof link === 'string' && link.startsWith('#')
|
||||||
|
}
|
||||||
|
|
||||||
function resolveTrailingSlashBehavior (to: string, resolve: Router['resolve']): string
|
function resolveTrailingSlashBehavior (to: string, resolve: Router['resolve']): string
|
||||||
function resolveTrailingSlashBehavior (to: RouteLocationRaw, resolve: Router['resolve']): Exclude<RouteLocationRaw, string>
|
function resolveTrailingSlashBehavior (to: RouteLocationRaw, resolve: Router['resolve']): Exclude<RouteLocationRaw, string>
|
||||||
function resolveTrailingSlashBehavior (to: RouteLocationRaw | undefined, resolve: Router['resolve']): RouteLocationRaw | RouteLocation | undefined {
|
function resolveTrailingSlashBehavior (to: RouteLocationRaw | undefined, resolve: Router['resolve']): RouteLocationRaw | RouteLocation | undefined {
|
||||||
@ -176,7 +182,9 @@ export function defineNuxtLink (options: NuxtLinkOptions) {
|
|||||||
|
|
||||||
// Resolves `to` value if it's a route location object
|
// Resolves `to` value if it's a route location object
|
||||||
const href = computed(() => {
|
const href = computed(() => {
|
||||||
if (!to.value || isAbsoluteUrl.value) { return to.value as string }
|
if (!to.value || isAbsoluteUrl.value || isHashLinkWithoutHashMode(to.value)) {
|
||||||
|
return to.value as string
|
||||||
|
}
|
||||||
|
|
||||||
if (isExternal.value) {
|
if (isExternal.value) {
|
||||||
const path = typeof to.value === 'object' && 'path' in to.value ? resolveRouteObject(to.value) : to.value
|
const path = typeof to.value === 'object' && 'path' in to.value ? resolveRouteObject(to.value) : to.value
|
||||||
@ -373,7 +381,7 @@ export function defineNuxtLink (options: NuxtLinkOptions) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
if (!isExternal.value && !hasTarget.value) {
|
if (!isExternal.value && !hasTarget.value && !isHashLinkWithoutHashMode(to.value)) {
|
||||||
const routerLinkProps: RouterLinkProps & VNodeProps & AllowedComponentProps & AnchorHTMLAttributes = {
|
const routerLinkProps: RouterLinkProps & VNodeProps & AllowedComponentProps & AnchorHTMLAttributes = {
|
||||||
ref: elRef,
|
ref: elRef,
|
||||||
to: to.value,
|
to: to.value,
|
||||||
|
@ -129,6 +129,16 @@ export default defineNuxtModule({
|
|||||||
'export const START_LOCATION = Symbol(\'router:start-location\')',
|
'export const START_LOCATION = Symbol(\'router:start-location\')',
|
||||||
].join('\n'),
|
].join('\n'),
|
||||||
})
|
})
|
||||||
|
// used by `<NuxtLink>`
|
||||||
|
addTemplate({
|
||||||
|
filename: 'router.options.mjs',
|
||||||
|
getContents: () => {
|
||||||
|
return [
|
||||||
|
'export const hashMode = false',
|
||||||
|
'export default {}',
|
||||||
|
].join('\n')
|
||||||
|
},
|
||||||
|
})
|
||||||
addTypeTemplate({
|
addTypeTemplate({
|
||||||
filename: 'types/middleware.d.ts',
|
filename: 'types/middleware.d.ts',
|
||||||
getContents: () => [
|
getContents: () => [
|
||||||
|
@ -119,6 +119,11 @@ describe('nuxt-link:isExternal', () => {
|
|||||||
expect(nuxtLink({ to: '/foo/bar', target: '_blank' }).type).toBe(EXTERNAL)
|
expect(nuxtLink({ to: '/foo/bar', target: '_blank' }).type).toBe(EXTERNAL)
|
||||||
expect(nuxtLink({ to: '/foo/bar?baz=qux', target: '_blank' }).type).toBe(EXTERNAL)
|
expect(nuxtLink({ to: '/foo/bar?baz=qux', target: '_blank' }).type).toBe(EXTERNAL)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('returns `true` if link starts with hash', () => {
|
||||||
|
expect(nuxtLink({ href: '#hash' }).type).toBe(EXTERNAL)
|
||||||
|
expect(nuxtLink({ to: '#hash' }).type).toBe(EXTERNAL)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('nuxt-link:propsOrAttributes', () => {
|
describe('nuxt-link:propsOrAttributes', () => {
|
||||||
|
2
test/mocks/router-options.ts
Normal file
2
test/mocks/router-options.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export default {}
|
||||||
|
export const hashMode = false
|
@ -8,6 +8,7 @@ export default defineConfig({
|
|||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
'#build/nuxt.config.mjs': resolve('./test/mocks/nuxt-config'),
|
'#build/nuxt.config.mjs': resolve('./test/mocks/nuxt-config'),
|
||||||
|
'#build/router.options': resolve('./test/mocks/router-options'),
|
||||||
'#internal/nuxt/paths': resolve('./test/mocks/paths'),
|
'#internal/nuxt/paths': resolve('./test/mocks/paths'),
|
||||||
'#build/app.config.mjs': resolve('./test/mocks/app-config'),
|
'#build/app.config.mjs': resolve('./test/mocks/app-config'),
|
||||||
'#app': resolve('./packages/nuxt/dist/app'),
|
'#app': resolve('./packages/nuxt/dist/app'),
|
||||||
|
Loading…
Reference in New Issue
Block a user