feat: allow function for NavItem link

pull/4963/head
Miroma 1 day ago
parent 6dfcdd3fe8
commit 9fa60e84f6
No known key found for this signature in database

@ -1,15 +1,22 @@
<script lang="ts" setup generic="T extends DefaultTheme.NavItemWithLink"> <script lang="ts" setup generic="T extends DefaultTheme.NavItemWithLink">
import type { DefaultTheme } from 'vitepress/theme' import type { DefaultTheme } from 'vitepress/theme'
import { computed } from 'vue'
import { useData } from '../composables/data' import { useData } from '../composables/data'
import { isActive } from '../../shared' import { isActive } from '../../shared'
import VPLink from './VPLink.vue' import VPLink from './VPLink.vue'
defineProps<{ const props = defineProps<{
item: T item: T
}>() }>()
const { page } = useData() const { page } = useData()
const href = computed(() =>
typeof props.item.link === 'function'
? props.item.link(page.value)
: props.item.link
)
defineOptions({ inheritAttrs: false }) defineOptions({ inheritAttrs: false })
</script> </script>
@ -20,11 +27,11 @@ defineOptions({ inheritAttrs: false })
:class="{ :class="{
active: isActive( active: isActive(
page.relativePath, page.relativePath,
item.activeMatch || item.link, item.activeMatch || href,
!!item.activeMatch !!item.activeMatch
) )
}" }"
:href="item.link" :href
:target="item.target" :target="item.target"
:rel="item.rel" :rel="item.rel"
:no-icon="item.noIcon" :no-icon="item.noIcon"

@ -17,7 +17,7 @@ const isChildActive = (navItem: DefaultTheme.NavItem) => {
if ('link' in navItem) { if ('link' in navItem) {
return isActive( return isActive(
page.value.relativePath, page.value.relativePath,
navItem.link, typeof navItem.link === "function" ? navItem.link(page.value) : navItem.link,
!!props.item.activeMatch !!props.item.activeMatch
) )
} }

@ -1,14 +1,21 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { DefaultTheme } from 'vitepress/theme' import type { DefaultTheme } from 'vitepress/theme'
import { computed } from 'vue'
import { useData } from '../composables/data' import { useData } from '../composables/data'
import { isActive } from '../../shared' import { isActive } from '../../shared'
import VPLink from './VPLink.vue' import VPLink from './VPLink.vue'
defineProps<{ const props = defineProps<{
item: DefaultTheme.NavItemWithLink item: DefaultTheme.NavItemWithLink
}>() }>()
const { page } = useData() const { page } = useData()
const href = computed(() =>
typeof props.item.link === 'function'
? props.item.link(page.value)
: props.item.link
)
</script> </script>
<template> <template>
@ -17,11 +24,11 @@ const { page } = useData()
VPNavBarMenuLink: true, VPNavBarMenuLink: true,
active: isActive( active: isActive(
page.relativePath, page.relativePath,
item.activeMatch || item.link, item.activeMatch || href,
!!item.activeMatch !!item.activeMatch
) )
}" }"
:href="item.link" :href
:target="item.target" :target="item.target"
:rel="item.rel" :rel="item.rel"
:no-icon="item.noIcon" :no-icon="item.noIcon"

@ -1,20 +1,29 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { DefaultTheme } from 'vitepress/theme' import type { DefaultTheme } from 'vitepress/theme'
import { inject } from 'vue' import { computed, inject } from 'vue'
import { useData } from '../composables/data'
import { navInjectionKey } from '../composables/nav' import { navInjectionKey } from '../composables/nav'
import VPLink from './VPLink.vue' import VPLink from './VPLink.vue'
defineProps<{ const props = defineProps<{
item: DefaultTheme.NavItemWithLink item: DefaultTheme.NavItemWithLink
}>() }>()
const { page } = useData()
const href = computed(() =>
typeof props.item.link === 'function'
? props.item.link(page.value)
: props.item.link
)
const { closeScreen } = inject(navInjectionKey)! const { closeScreen } = inject(navInjectionKey)!
</script> </script>
<template> <template>
<VPLink <VPLink
class="VPNavScreenMenuGroupLink" class="VPNavScreenMenuGroupLink"
:href="item.link" :href
:target="item.target" :target="item.target"
:rel="item.rel" :rel="item.rel"
:no-icon="item.noIcon" :no-icon="item.noIcon"

@ -1,20 +1,29 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { DefaultTheme } from 'vitepress/theme' import type { DefaultTheme } from 'vitepress/theme'
import { inject } from 'vue' import { computed, inject } from 'vue'
import { useData } from '../composables/data'
import { navInjectionKey } from '../composables/nav' import { navInjectionKey } from '../composables/nav'
import VPLink from './VPLink.vue' import VPLink from './VPLink.vue'
defineProps<{ const props = defineProps<{
item: DefaultTheme.NavItemWithLink item: DefaultTheme.NavItemWithLink
}>() }>()
const { page } = useData()
const href = computed(() =>
typeof props.item.link === 'function'
? props.item.link(page.value)
: props.item.link
)
const { closeScreen } = inject(navInjectionKey)! const { closeScreen } = inject(navInjectionKey)!
</script> </script>
<template> <template>
<VPLink <VPLink
class="VPNavScreenMenuLink" class="VPNavScreenMenuLink"
:href="item.link" :href
:target="item.target" :target="item.target"
:rel="item.rel" :rel="item.rel"
:no-icon="item.noIcon" :no-icon="item.noIcon"

@ -171,7 +171,7 @@ export namespace DefaultTheme {
export interface NavItemWithLink { export interface NavItemWithLink {
text: string text: string
link: string link: string | ((payload: PageData) => string)
items?: never items?: never
/** /**

Loading…
Cancel
Save