mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-28 08:32:06 +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({
|
||||
name: componentName,
|
||||
props: {
|
||||
@ -161,7 +160,9 @@ export function defineNuxtLink (options: NuxtLinkOptions) {
|
||||
|
||||
const prefetched = ref(false)
|
||||
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(() => {
|
||||
checkPropConflicts(props, 'to', 'href')
|
||||
@ -170,7 +171,7 @@ export function defineNuxtLink (options: NuxtLinkOptions) {
|
||||
const href = computed(() => {
|
||||
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 forceAnchorTag = props.external
|
||||
if (forceAnchorTag || isAbsoluteLink.value) {
|
||||
@ -209,7 +210,7 @@ export function defineNuxtLink (options: NuxtLinkOptions) {
|
||||
})
|
||||
|
||||
const anchorProps = computed(() => {
|
||||
const to = link.value
|
||||
const to = href.value
|
||||
// Resolves `target` value
|
||||
const target = props.target || null
|
||||
|
||||
@ -241,8 +242,10 @@ export function defineNuxtLink (options: NuxtLinkOptions) {
|
||||
unobserve = null
|
||||
|
||||
await Promise.all([
|
||||
nuxtApp.hooks.callHook('link:prefetch', href.value).catch(() => {}),
|
||||
as.value === 'RouterLink' && preloadRouteComponents(link.value, router).catch(() => {})
|
||||
nuxtApp.hooks.callHook('link:prefetch', href.value).catch(() => {
|
||||
}),
|
||||
as.value === 'RouterLink' && preloadRouteComponents(link.value, router).catch(() => {
|
||||
})
|
||||
])
|
||||
prefetched.value = true
|
||||
})
|
||||
@ -251,7 +254,9 @@ export function defineNuxtLink (options: NuxtLinkOptions) {
|
||||
})
|
||||
})
|
||||
onBeforeUnmount(() => {
|
||||
if (idleId) { cancelIdleCallback(idleId) }
|
||||
if (idleId) {
|
||||
cancelIdleCallback(idleId)
|
||||
}
|
||||
unobserve?.()
|
||||
unobserve = null
|
||||
})
|
||||
@ -261,7 +266,7 @@ export function defineNuxtLink (options: NuxtLinkOptions) {
|
||||
if (import.meta.dev && import.meta.server && !props.custom) {
|
||||
const isNuxtLinkChild = inject(NuxtLinkDevKeySymbol, false)
|
||||
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 {
|
||||
provide(NuxtLinkDevKeySymbol, true)
|
||||
}
|
||||
@ -277,14 +282,13 @@ export function defineNuxtLink (options: NuxtLinkOptions) {
|
||||
)
|
||||
}
|
||||
|
||||
if (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)
|
||||
return null
|
||||
if (import.meta.dev && typeof link.value === 'object') {
|
||||
console.warn('[nuxt] [NuxtLink] Providing `to` as a vue-router route is not supported with external links.', href.value)
|
||||
}
|
||||
|
||||
const navigate = () => {
|
||||
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 navigateTo(anchorProps.value.href, {
|
||||
|
@ -526,55 +526,164 @@ describe('nuxt links', () => {
|
||||
const data: Record<string, string[]> = {}
|
||||
for (const selector of ['nuxt-link', 'router-link', 'link-with-trailing-slash', 'link-without-trailing-slash']) {
|
||||
data[selector] = []
|
||||
for (const match of html.matchAll(new RegExp(`href="([^"]*)"[^>]*class="[^"]*\\b${selector}\\b`, 'g'))) {
|
||||
data[selector].push(match[1])
|
||||
// extract all anchor tags
|
||||
for (const match of html.matchAll(new RegExp(`<a[^>]+class="[^"]*${selector}[^"]*"[^>]*>`, 'g'))) {
|
||||
data[selector].push(match)
|
||||
}
|
||||
}
|
||||
expect(data).toMatchInlineSnapshot(`
|
||||
{
|
||||
"link-with-trailing-slash": [
|
||||
"/",
|
||||
"/nuxt-link/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",
|
||||
"/nuxt-link/trailing-slash/",
|
||||
"/nuxt-link/trailing-slash/?with-state=true",
|
||||
"/nuxt-link/trailing-slash/?without-state=true",
|
||||
"https://example.com/page.html",
|
||||
[
|
||||
"<a href="/" 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/" 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/?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": [
|
||||
"/",
|
||||
"/nuxt-link/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",
|
||||
"/nuxt-link/trailing-slash",
|
||||
"/nuxt-link/trailing-slash?with-state=true",
|
||||
"/nuxt-link/trailing-slash?without-state=true",
|
||||
"https://example.com/page.html",
|
||||
[
|
||||
"<a href="/" 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" 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?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/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",
|
||||
"/nuxt-link/trailing-slash",
|
||||
"/nuxt-link/trailing-slash?with-state=true",
|
||||
"/nuxt-link/trailing-slash?without-state=true",
|
||||
"https://example.com/page.html",
|
||||
[
|
||||
"<a href="/" 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/" 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/?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": [
|
||||
"/",
|
||||
"/nuxt-link/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",
|
||||
"/nuxt-link/trailing-slash",
|
||||
"/nuxt-link/trailing-slash?with-state=true",
|
||||
"/nuxt-link/trailing-slash?without-state=true",
|
||||
"/nuxt-link/https://example.com/page.html",
|
||||
[
|
||||
"<a href="/" 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/" 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/?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'
|
||||
})
|
||||
const links = [
|
||||
'/',
|
||||
'/nuxt-link/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',
|
||||
{ name: 'nuxt-link-trailing-slash' },
|
||||
{ query: { 'with-state': 'true' }, state: { foo: 'bar' } },
|
||||
{ query: { 'without-state': 'true' } },
|
||||
'https://example.com/page.html'
|
||||
{ to: '/', },
|
||||
{ to: '/nuxt-link/trailing-slash',},
|
||||
{ to: '/nuxt-link/trailing-slash/',},
|
||||
{ to: '/nuxt-link/trailing-slash?test=true&thing=other/thing#thing-other',},
|
||||
{ to: '/nuxt-link/trailing-slash/?test=true&thing=other/thing#thing-other',},
|
||||
{ to: { name: 'nuxt-link-trailing-slash' },},
|
||||
{ to: { query: { 'with-state': 'true' }, state: { foo: 'bar' } },},
|
||||
{ to: { query: { 'without-state': 'true' } }},
|
||||
// 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
|
||||
|
||||
const route = useRoute()
|
||||
@ -42,13 +49,13 @@ const windowState = computed(() => {
|
||||
:key="index"
|
||||
>
|
||||
<LinkWithTrailingSlash
|
||||
:to="link"
|
||||
v-bind="link"
|
||||
class="link-with-trailing-slash"
|
||||
>
|
||||
<LinkWithTrailingSlash
|
||||
v-slot="{ href }"
|
||||
custom
|
||||
:to="link"
|
||||
v-bind="link"
|
||||
>
|
||||
{{ href }}
|
||||
</LinkWithTrailingSlash>
|
||||
@ -63,13 +70,13 @@ const windowState = computed(() => {
|
||||
:key="index"
|
||||
>
|
||||
<LinkWithoutTrailingSlash
|
||||
:to="link"
|
||||
v-bind="link"
|
||||
class="link-without-trailing-slash"
|
||||
>
|
||||
<LinkWithoutTrailingSlash
|
||||
v-slot="{ href }"
|
||||
custom
|
||||
:to="link"
|
||||
v-bind="link"
|
||||
>
|
||||
{{ href }}
|
||||
</LinkWithoutTrailingSlash>
|
||||
@ -84,13 +91,13 @@ const windowState = computed(() => {
|
||||
:key="index"
|
||||
>
|
||||
<NuxtLink
|
||||
:to="link"
|
||||
v-bind="link"
|
||||
class="nuxt-link"
|
||||
>
|
||||
<NuxtLink
|
||||
v-slot="{ href }"
|
||||
custom
|
||||
:to="link"
|
||||
v-bind="link"
|
||||
>
|
||||
{{ href }}
|
||||
</NuxtLink>
|
||||
@ -105,13 +112,13 @@ const windowState = computed(() => {
|
||||
:key="index"
|
||||
>
|
||||
<RouterLink
|
||||
:to="link"
|
||||
v-bind="link"
|
||||
class="router-link"
|
||||
>
|
||||
<RouterLink
|
||||
v-slot="{ href }"
|
||||
custom
|
||||
:to="link"
|
||||
v-bind="link"
|
||||
>
|
||||
{{ href }}
|
||||
</RouterLink>
|
||||
|
Loading…
Reference in New Issue
Block a user