Link
Provides a custom <NuxtLink> component to handle any kind of links within your application.
Examples
Basic
Prop | Default | Type | Description |
---|---|---|---|
inactiveClass | - | string | The class to apply when the link is inactive. |
exact | false | boolean | Trigger the link active class only on exact matches of the path . |
exactQuery | false | boolean | Trigger the link active class only on exact matches of the query . |
exactHash | false | boolean | Trigger the link active class only on exact matches of the hash . |
Read more in Nuxt Link Props
Preview
Code
<template>
<div class="flex gap-4">
<NLink
to="/components/link"
active-class="text-success"
>
Active Link
</NLink>
<NLink
to="/components/link/"
exact-active-class="text-lime"
exact
>
Exact Active Link
</NLink>
<NLink
to="https://github.com/una-ui/una-ui"
target="_blank"
inactive-class="text-gray"
>
Inactive Link
</NLink>
<NLink
to="/components/link?search=something"
active-class="text-warning"
exact-query
>
Exact query
</NLink>
<NLink
to="/components/link#something"
active-class="text-pink"
exact-hash
>
Exact Hash
</NLink>
</div>
</template>
Slots
Name | Props | Description |
---|---|---|
default | - | The content of the link. |
Props
types/link.ts
import type { NuxtLinkProps } from 'nuxt/app'
export interface NLinkProps extends NuxtLinkProps {
/**
* Manually enable/disable the exact match
*
* @default false
*/
exact?: boolean
/**
* Manually enable/disable the exact match for the query string
*
* @default false
*/
exactQuery?: boolean
/**
* Manually enable/disable the exact match for the hash
*
* @default false
*/
exactHash?: boolean
/**
* Active classes to apply when the link is inactive
*
* @example 'text-primary'
*/
inactiveClass?: string
/**
* Useful in combination with `NavLink` to apply the active class to the parent element
*
*/
navLinkActive?: string
/**
* Useful in combination with `NavLink` to apply the inactive class to the parent element
*/
navLinkInactive?: string
}
Presets
shortcuts/link.ts
type LinkPrefix = 'link'
export const staticLink: Record<LinkPrefix, string> = {
// base
link: '',
}
export const dynamicLink: [RegExp, (params: RegExpExecArray) => string][] = [
// dynamic preset
]
export const link = [
...dynamicLink,
staticLink,
]
Components
Link.vue
<script lang="ts">
import type { PropType } from 'vue'
import type { NLinkProps } from '../../types'
import { NuxtLink } from '#components'
import { isEqual } from 'ohash'
import { defineComponent } from 'vue'
export default defineComponent({
inheritAttrs: false,
props: {
...NuxtLink.props,
// config
exact: {
type: Boolean as PropType<NLinkProps['exact']>,
default: false,
},
exactQuery: {
type: Boolean as PropType<NLinkProps['exactQuery']>,
default: false,
},
exactHash: {
type: Boolean as PropType<NLinkProps['exactHash']>,
default: false,
},
// styling
inactiveClass: {
type: String as PropType<NLinkProps['inactiveClass']>,
default: undefined,
},
// preset
navLinkActive: {
type: String as PropType<NLinkProps['navLinkActive']>,
default: undefined,
},
navLinkInactive: {
type: String as PropType<NLinkProps['navLinkInactive']>,
default: undefined,
},
},
setup(props: any) {
function resolveLinkClass(route: any, $route: any, { isActive, isExactActive }: { isActive: boolean, isExactActive: boolean }): string | null {
if (props.exactQuery && !isEqual(route.query, $route.query))
return props.inactiveClass
if (props.exactHash && !isEqual(route.hash, $route.hash))
return props.inactiveClass
if (props.exact && isExactActive)
return props.exactActiveClass
if (!props.exact && isActive)
return props.activeClass
return props.inactiveClass
}
function resolveNavLinkActive(route: any, $route: any, { isActive, isExactActive }: { isActive: boolean, isExactActive: boolean }): string | null {
if (props.exactQuery && !isEqual(route.query, $route.query))
return null
if (props.exactHash && !isEqual(route.hash, $route.hash))
return null
if (props.exact && isExactActive)
return props.navLinkActive
if (!props.exact && isActive)
return props.navLinkActive
return null
}
function resolveNavLinkInactive(route: any, $route: any, { isActive, isExactActive }: { isActive: boolean, isExactActive: boolean }): string | null {
if (props.exactQuery && !isEqual(route.query, $route.query))
return props.navLinkInactive
if (props.exactHash && !isEqual(route.hash, $route.hash))
return props.navLinkInactive
if ((!props.exact && isActive) || (props.exact && isExactActive))
return null
return props.navLinkInactive
}
return {
resolveLinkClass,
resolveNavLinkActive,
resolveNavLinkInactive,
}
},
})
</script>
<template>
<!-- eslint-disable vue/no-template-shadow -->
<NuxtLink
v-slot="{ route, href, target, rel, navigate, isActive, isExactActive, isExternal, exact }"
v-bind="$props"
custom
>
<a
v-bind="$attrs"
:href="href"
:rel="rel"
:target="target"
:class="resolveLinkClass(route, $route, { isActive, isExactActive })"
:nav-link-active="resolveNavLinkActive(route, $route, { isActive, isExactActive })"
:nav-link-inactive="resolveNavLinkInactive(route, $route, { isActive, isExactActive })"
@click="(e) => !isExternal && navigate(e)"
>
<slot v-bind="{ isActive: exact ? isExactActive : isActive }" />
</a>
</NuxtLink>
</template>