๐ข Link
Basic
NLink
is a custom NuxtLink
component that provides additional functionality for rendering links to pages in your application.
Prop | Type | Description |
---|---|---|
inactiveClass | string | The class to apply when the link is inactive. |
exact | boolean | Trigger the link active class only on exact matches of the path . |
exactQuery | boolean | Trigger the link active class only on exact matches of the query . |
exactHash | boolean | Trigger the link active class only on exact matches of the hash . |
You can also use any prop provided by the NuxtLink component.
You can take a look and click at examples of different usage below:
Props
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
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,
]
Component
<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>