mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-24 14:45:15 +00:00
chore: clean up
This commit is contained in:
parent
da7a9e952e
commit
5ecde8037c
@ -67,7 +67,6 @@ export function defineNuxtLink (options: NuxtLinkOptions) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO migrate to TypeScript props
|
|
||||||
return defineComponent({
|
return defineComponent({
|
||||||
name: componentName,
|
name: componentName,
|
||||||
props: {
|
props: {
|
||||||
@ -161,7 +160,9 @@ export function defineNuxtLink (options: NuxtLinkOptions) {
|
|||||||
|
|
||||||
const prefetched = ref(false)
|
const prefetched = ref(false)
|
||||||
const el = import.meta.server ? undefined : ref<HTMLElement | null>(null)
|
const el = import.meta.server ? undefined : ref<HTMLElement | null>(null)
|
||||||
const elRef = import.meta.server ? undefined : (ref: any) => { el!.value = props.custom ? ref?.$el?.nextElementSibling : ref?.$el }
|
const elRef = import.meta.server ? undefined : (ref: any) => {
|
||||||
|
el!.value = props.custom ? ref?.$el?.nextElementSibling : ref?.$el
|
||||||
|
}
|
||||||
|
|
||||||
const link = computed(() => {
|
const link = computed(() => {
|
||||||
checkPropConflicts(props, 'to', 'href')
|
checkPropConflicts(props, 'to', 'href')
|
||||||
@ -170,7 +171,7 @@ export function defineNuxtLink (options: NuxtLinkOptions) {
|
|||||||
const href = computed(() => {
|
const href = computed(() => {
|
||||||
return typeof link.value === 'string' ? link.value : router.resolve(link.value).path
|
return typeof link.value === 'string' ? link.value : router.resolve(link.value).path
|
||||||
})
|
})
|
||||||
const isAbsoluteLink = computed(() => hasProtocol(href.value, { acceptRelative: true }))
|
const isAbsoluteLink = computed(() => hasProtocol(href.value, {acceptRelative: true}))
|
||||||
const as = computed(() => {
|
const as = computed(() => {
|
||||||
const forceAnchorTag = props.external
|
const forceAnchorTag = props.external
|
||||||
if (forceAnchorTag || isAbsoluteLink.value) {
|
if (forceAnchorTag || isAbsoluteLink.value) {
|
||||||
@ -209,7 +210,7 @@ export function defineNuxtLink (options: NuxtLinkOptions) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const anchorProps = computed(() => {
|
const anchorProps = computed(() => {
|
||||||
const to = link.value
|
const to = href.value
|
||||||
// Resolves `target` value
|
// Resolves `target` value
|
||||||
const target = props.target || null
|
const target = props.target || null
|
||||||
|
|
||||||
@ -241,8 +242,10 @@ export function defineNuxtLink (options: NuxtLinkOptions) {
|
|||||||
unobserve = null
|
unobserve = null
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
nuxtApp.hooks.callHook('link:prefetch', href.value).catch(() => {}),
|
nuxtApp.hooks.callHook('link:prefetch', href.value).catch(() => {
|
||||||
as.value === 'RouterLink' && preloadRouteComponents(link.value, router).catch(() => {})
|
}),
|
||||||
|
as.value === 'RouterLink' && preloadRouteComponents(link.value, router).catch(() => {
|
||||||
|
})
|
||||||
])
|
])
|
||||||
prefetched.value = true
|
prefetched.value = true
|
||||||
})
|
})
|
||||||
@ -251,7 +254,9 @@ export function defineNuxtLink (options: NuxtLinkOptions) {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
if (idleId) { cancelIdleCallback(idleId) }
|
if (idleId) {
|
||||||
|
cancelIdleCallback(idleId)
|
||||||
|
}
|
||||||
unobserve?.()
|
unobserve?.()
|
||||||
unobserve = null
|
unobserve = null
|
||||||
})
|
})
|
||||||
@ -261,7 +266,7 @@ export function defineNuxtLink (options: NuxtLinkOptions) {
|
|||||||
if (import.meta.dev && import.meta.server && !props.custom) {
|
if (import.meta.dev && import.meta.server && !props.custom) {
|
||||||
const isNuxtLinkChild = inject(NuxtLinkDevKeySymbol, false)
|
const isNuxtLinkChild = inject(NuxtLinkDevKeySymbol, false)
|
||||||
if (isNuxtLinkChild) {
|
if (isNuxtLinkChild) {
|
||||||
console.log('[nuxt] [NuxtLink] You can\'t nest one <a> inside another <a>. This will cause a hydration error on client-side. You can pass the `custom` prop to take full control of the markup.')
|
console.warn('[nuxt] [NuxtLink] You can\'t nest one <a> inside another <a>. This will cause a hydration error on client-side. You can pass the `custom` prop to take full control of the markup.')
|
||||||
} else {
|
} else {
|
||||||
provide(NuxtLinkDevKeySymbol, true)
|
provide(NuxtLinkDevKeySymbol, true)
|
||||||
}
|
}
|
||||||
@ -277,14 +282,13 @@ export function defineNuxtLink (options: NuxtLinkOptions) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof link.value === 'object') {
|
if (import.meta.dev && typeof link.value === 'object') {
|
||||||
import.meta.dev && console.log('[nuxt] [NuxtLink] Providing `to` as a vue-router route is not supported with external links.', link.value)
|
console.warn('[nuxt] [NuxtLink] Providing `to` as a vue-router route is not supported with external links.', href.value)
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const navigate = () => {
|
const navigate = () => {
|
||||||
if (isAbsoluteLink.value) {
|
if (isAbsoluteLink.value) {
|
||||||
import.meta.dev && console.log('[nuxt] [NuxtLink] Navigating to an absolute link using `navigate()` isn\'t supported', anchorProps.value.href)
|
import.meta.dev && console.warn('[nuxt] [NuxtLink] Navigating to an absolute link using `navigate()` isn\'t supported.', href.value)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return navigateTo(anchorProps.value.href, {
|
return navigateTo(anchorProps.value.href, {
|
||||||
|
@ -526,55 +526,164 @@ describe('nuxt links', () => {
|
|||||||
const data: Record<string, string[]> = {}
|
const data: Record<string, string[]> = {}
|
||||||
for (const selector of ['nuxt-link', 'router-link', 'link-with-trailing-slash', 'link-without-trailing-slash']) {
|
for (const selector of ['nuxt-link', 'router-link', 'link-with-trailing-slash', 'link-without-trailing-slash']) {
|
||||||
data[selector] = []
|
data[selector] = []
|
||||||
for (const match of html.matchAll(new RegExp(`href="([^"]*)"[^>]*class="[^"]*\\b${selector}\\b`, 'g'))) {
|
// extract all anchor tags
|
||||||
data[selector].push(match[1])
|
for (const match of html.matchAll(new RegExp(`<a[^>]+class="[^"]*${selector}[^"]*"[^>]*>`, 'g'))) {
|
||||||
|
data[selector].push(match)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect(data).toMatchInlineSnapshot(`
|
expect(data).toMatchInlineSnapshot(`
|
||||||
{
|
{
|
||||||
"link-with-trailing-slash": [
|
"link-with-trailing-slash": [
|
||||||
"/",
|
[
|
||||||
"/nuxt-link/trailing-slash/",
|
"<a href="/" class="link-with-trailing-slash">",
|
||||||
"/nuxt-link/trailing-slash/",
|
],
|
||||||
"/nuxt-link/trailing-slash/?test=true&thing=other/thing#thing-other",
|
[
|
||||||
"/nuxt-link/trailing-slash/?test=true&thing=other/thing#thing-other",
|
"<a aria-current="page" href="/nuxt-link/trailing-slash/" class="foo-active-class bar-exact-active-class link-with-trailing-slash">",
|
||||||
"/nuxt-link/trailing-slash/",
|
],
|
||||||
"/nuxt-link/trailing-slash/?with-state=true",
|
[
|
||||||
"/nuxt-link/trailing-slash/?without-state=true",
|
"<a aria-current="page" href="/nuxt-link/trailing-slash/" class="foo-active-class bar-exact-active-class link-with-trailing-slash">",
|
||||||
"https://example.com/page.html",
|
],
|
||||||
|
[
|
||||||
|
"<a aria-current="page" href="/nuxt-link/trailing-slash/?test=true&thing=other/thing#thing-other" class="foo-active-class bar-exact-active-class link-with-trailing-slash">",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"<a aria-current="page" href="/nuxt-link/trailing-slash/?test=true&thing=other/thing#thing-other" class="foo-active-class bar-exact-active-class link-with-trailing-slash">",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"<a aria-current="page" href="/nuxt-link/trailing-slash/" class="foo-active-class bar-exact-active-class link-with-trailing-slash">",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"<a aria-current="page" href="/nuxt-link/trailing-slash/?with-state=true" class="foo-active-class bar-exact-active-class link-with-trailing-slash">",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"<a aria-current="page" href="/nuxt-link/trailing-slash/?without-state=true" class="foo-active-class bar-exact-active-class link-with-trailing-slash">",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"<a href="https://example.com/page.html" rel="noopener noreferrer" class="link-with-trailing-slash">",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"<a href="/nuxt-link/https://example.com/page.html" rel="noopener noreferrer" class="link-with-trailing-slash">",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"<a href="/foo" rel="noopener noreferrer" class="link-with-trailing-slash">",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"<a href="/foo" rel="noopener noreferrer" class="link-with-trailing-slash">",
|
||||||
|
],
|
||||||
],
|
],
|
||||||
"link-without-trailing-slash": [
|
"link-without-trailing-slash": [
|
||||||
"/",
|
[
|
||||||
"/nuxt-link/trailing-slash",
|
"<a href="/" class="link-without-trailing-slash">",
|
||||||
"/nuxt-link/trailing-slash",
|
],
|
||||||
"/nuxt-link/trailing-slash?test=true&thing=other/thing#thing-other",
|
[
|
||||||
"/nuxt-link/trailing-slash?test=true&thing=other/thing#thing-other",
|
"<a aria-current="page" href="/nuxt-link/trailing-slash" class="foo-active-class bar-exact-active-class link-without-trailing-slash">",
|
||||||
"/nuxt-link/trailing-slash",
|
],
|
||||||
"/nuxt-link/trailing-slash?with-state=true",
|
[
|
||||||
"/nuxt-link/trailing-slash?without-state=true",
|
"<a aria-current="page" href="/nuxt-link/trailing-slash" class="foo-active-class bar-exact-active-class link-without-trailing-slash">",
|
||||||
"https://example.com/page.html",
|
],
|
||||||
|
[
|
||||||
|
"<a aria-current="page" href="/nuxt-link/trailing-slash?test=true&thing=other/thing#thing-other" class="foo-active-class bar-exact-active-class link-without-trailing-slash">",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"<a aria-current="page" href="/nuxt-link/trailing-slash?test=true&thing=other/thing#thing-other" class="foo-active-class bar-exact-active-class link-without-trailing-slash">",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"<a aria-current="page" href="/nuxt-link/trailing-slash" class="foo-active-class bar-exact-active-class link-without-trailing-slash">",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"<a aria-current="page" href="/nuxt-link/trailing-slash?with-state=true" class="foo-active-class bar-exact-active-class link-without-trailing-slash">",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"<a aria-current="page" href="/nuxt-link/trailing-slash?without-state=true" class="foo-active-class bar-exact-active-class link-without-trailing-slash">",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"<a href="https://example.com/page.html" rel="noopener noreferrer" class="link-without-trailing-slash">",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"<a href="/nuxt-link/https://example.com/page.html" rel="noopener noreferrer" class="link-without-trailing-slash">",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"<a href="/foo" rel="noopener noreferrer" class="link-without-trailing-slash">",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"<a href="/foo" rel="noopener noreferrer" class="link-without-trailing-slash">",
|
||||||
|
],
|
||||||
],
|
],
|
||||||
"nuxt-link": [
|
"nuxt-link": [
|
||||||
"/",
|
[
|
||||||
"/nuxt-link/trailing-slash",
|
"<a href="/" class="nuxt-link">",
|
||||||
"/nuxt-link/trailing-slash/",
|
],
|
||||||
"/nuxt-link/trailing-slash?test=true&thing=other/thing#thing-other",
|
[
|
||||||
"/nuxt-link/trailing-slash/?test=true&thing=other/thing#thing-other",
|
"<a aria-current="page" href="/nuxt-link/trailing-slash" class="foo-active-class bar-exact-active-class nuxt-link">",
|
||||||
"/nuxt-link/trailing-slash",
|
],
|
||||||
"/nuxt-link/trailing-slash?with-state=true",
|
[
|
||||||
"/nuxt-link/trailing-slash?without-state=true",
|
"<a aria-current="page" href="/nuxt-link/trailing-slash/" class="foo-active-class bar-exact-active-class nuxt-link">",
|
||||||
"https://example.com/page.html",
|
],
|
||||||
|
[
|
||||||
|
"<a aria-current="page" href="/nuxt-link/trailing-slash?test=true&thing=other/thing#thing-other" class="foo-active-class bar-exact-active-class nuxt-link">",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"<a aria-current="page" href="/nuxt-link/trailing-slash/?test=true&thing=other/thing#thing-other" class="foo-active-class bar-exact-active-class nuxt-link">",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"<a aria-current="page" href="/nuxt-link/trailing-slash" class="foo-active-class bar-exact-active-class nuxt-link">",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"<a aria-current="page" href="/nuxt-link/trailing-slash?with-state=true" class="foo-active-class bar-exact-active-class nuxt-link">",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"<a aria-current="page" href="/nuxt-link/trailing-slash?without-state=true" class="foo-active-class bar-exact-active-class nuxt-link">",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"<a href="https://example.com/page.html" rel="noopener noreferrer" class="nuxt-link">",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"<a href="/nuxt-link/https://example.com/page.html" rel="noopener noreferrer" class="nuxt-link">",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"<a href="/foo" rel="noopener noreferrer" class="nuxt-link">",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"<a href="/foo" rel="noopener noreferrer" class="nuxt-link">",
|
||||||
|
],
|
||||||
],
|
],
|
||||||
"router-link": [
|
"router-link": [
|
||||||
"/",
|
[
|
||||||
"/nuxt-link/trailing-slash",
|
"<a href="/" class="router-link">",
|
||||||
"/nuxt-link/trailing-slash/",
|
],
|
||||||
"/nuxt-link/trailing-slash?test=true&thing=other/thing#thing-other",
|
[
|
||||||
"/nuxt-link/trailing-slash/?test=true&thing=other/thing#thing-other",
|
"<a aria-current="page" href="/nuxt-link/trailing-slash" class="foo-active-class bar-exact-active-class router-link">",
|
||||||
"/nuxt-link/trailing-slash",
|
],
|
||||||
"/nuxt-link/trailing-slash?with-state=true",
|
[
|
||||||
"/nuxt-link/trailing-slash?without-state=true",
|
"<a aria-current="page" href="/nuxt-link/trailing-slash/" class="foo-active-class bar-exact-active-class router-link">",
|
||||||
"/nuxt-link/https://example.com/page.html",
|
],
|
||||||
|
[
|
||||||
|
"<a aria-current="page" href="/nuxt-link/trailing-slash?test=true&thing=other/thing#thing-other" class="foo-active-class bar-exact-active-class router-link">",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"<a aria-current="page" href="/nuxt-link/trailing-slash/?test=true&thing=other/thing#thing-other" class="foo-active-class bar-exact-active-class router-link">",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"<a aria-current="page" href="/nuxt-link/trailing-slash" class="foo-active-class bar-exact-active-class router-link">",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"<a aria-current="page" href="/nuxt-link/trailing-slash?with-state=true" class="foo-active-class bar-exact-active-class router-link">",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"<a aria-current="page" href="/nuxt-link/trailing-slash?without-state=true" class="foo-active-class bar-exact-active-class router-link">",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"<a href="/nuxt-link/https://example.com/page.html" class="router-link">",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"<a href="/nuxt-link/https://example.com/page.html" class="router-link" external="true">",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"<a href="/foo" class="router-link" external="true">",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"<a href="/foo" class="router-link" external="true">",
|
||||||
|
],
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
`)
|
`)
|
||||||
|
@ -6,15 +6,22 @@ const LinkWithoutTrailingSlash = defineNuxtLink({
|
|||||||
trailingSlash: 'remove'
|
trailingSlash: 'remove'
|
||||||
})
|
})
|
||||||
const links = [
|
const links = [
|
||||||
'/',
|
{ to: '/', },
|
||||||
'/nuxt-link/trailing-slash',
|
{ to: '/nuxt-link/trailing-slash',},
|
||||||
'/nuxt-link/trailing-slash/',
|
{ to: '/nuxt-link/trailing-slash/',},
|
||||||
'/nuxt-link/trailing-slash?test=true&thing=other/thing#thing-other',
|
{ to: '/nuxt-link/trailing-slash?test=true&thing=other/thing#thing-other',},
|
||||||
'/nuxt-link/trailing-slash/?test=true&thing=other/thing#thing-other',
|
{ to: '/nuxt-link/trailing-slash/?test=true&thing=other/thing#thing-other',},
|
||||||
{ name: 'nuxt-link-trailing-slash' },
|
{ to: { name: 'nuxt-link-trailing-slash' },},
|
||||||
{ query: { 'with-state': 'true' }, state: { foo: 'bar' } },
|
{ to: { query: { 'with-state': 'true' }, state: { foo: 'bar' } },},
|
||||||
{ query: { 'without-state': 'true' } },
|
{ to: { query: { 'without-state': 'true' } }},
|
||||||
'https://example.com/page.html'
|
// Trailing slashes are applied to implicit external links
|
||||||
|
{ to: 'https://example.com/page.html' },
|
||||||
|
// Explicit external links do not when using vue-router object
|
||||||
|
{ to: { path: 'https://example.com/page.html' }, external: true },
|
||||||
|
// Explicit external links (that are relative) that use vue-router object adds base and trailing slash
|
||||||
|
{ to: { path: '/foo' }, external: true },
|
||||||
|
// Explicit external for relative path trailing slashes is applied
|
||||||
|
{ to: '/foo', external: true },
|
||||||
] as const
|
] as const
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
@ -42,13 +49,13 @@ const windowState = computed(() => {
|
|||||||
:key="index"
|
:key="index"
|
||||||
>
|
>
|
||||||
<LinkWithTrailingSlash
|
<LinkWithTrailingSlash
|
||||||
:to="link"
|
v-bind="link"
|
||||||
class="link-with-trailing-slash"
|
class="link-with-trailing-slash"
|
||||||
>
|
>
|
||||||
<LinkWithTrailingSlash
|
<LinkWithTrailingSlash
|
||||||
v-slot="{ href }"
|
v-slot="{ href }"
|
||||||
custom
|
custom
|
||||||
:to="link"
|
v-bind="link"
|
||||||
>
|
>
|
||||||
{{ href }}
|
{{ href }}
|
||||||
</LinkWithTrailingSlash>
|
</LinkWithTrailingSlash>
|
||||||
@ -63,13 +70,13 @@ const windowState = computed(() => {
|
|||||||
:key="index"
|
:key="index"
|
||||||
>
|
>
|
||||||
<LinkWithoutTrailingSlash
|
<LinkWithoutTrailingSlash
|
||||||
:to="link"
|
v-bind="link"
|
||||||
class="link-without-trailing-slash"
|
class="link-without-trailing-slash"
|
||||||
>
|
>
|
||||||
<LinkWithoutTrailingSlash
|
<LinkWithoutTrailingSlash
|
||||||
v-slot="{ href }"
|
v-slot="{ href }"
|
||||||
custom
|
custom
|
||||||
:to="link"
|
v-bind="link"
|
||||||
>
|
>
|
||||||
{{ href }}
|
{{ href }}
|
||||||
</LinkWithoutTrailingSlash>
|
</LinkWithoutTrailingSlash>
|
||||||
@ -84,13 +91,13 @@ const windowState = computed(() => {
|
|||||||
:key="index"
|
:key="index"
|
||||||
>
|
>
|
||||||
<NuxtLink
|
<NuxtLink
|
||||||
:to="link"
|
v-bind="link"
|
||||||
class="nuxt-link"
|
class="nuxt-link"
|
||||||
>
|
>
|
||||||
<NuxtLink
|
<NuxtLink
|
||||||
v-slot="{ href }"
|
v-slot="{ href }"
|
||||||
custom
|
custom
|
||||||
:to="link"
|
v-bind="link"
|
||||||
>
|
>
|
||||||
{{ href }}
|
{{ href }}
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
@ -105,13 +112,13 @@ const windowState = computed(() => {
|
|||||||
:key="index"
|
:key="index"
|
||||||
>
|
>
|
||||||
<RouterLink
|
<RouterLink
|
||||||
:to="link"
|
v-bind="link"
|
||||||
class="router-link"
|
class="router-link"
|
||||||
>
|
>
|
||||||
<RouterLink
|
<RouterLink
|
||||||
v-slot="{ href }"
|
v-slot="{ href }"
|
||||||
custom
|
custom
|
||||||
:to="link"
|
v-bind="link"
|
||||||
>
|
>
|
||||||
{{ href }}
|
{{ href }}
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
|
Loading…
Reference in New Issue
Block a user