perf: 导航栏链接支持传入文件路径
This commit is contained in:
parent
e6357fc992
commit
c1a9868ead
@ -1,7 +1,7 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue'
|
||||
import { useRouter } from 'vuepress/client'
|
||||
import { EXTERNAL_URL_RE, normalizeLink } from '../utils/index.js'
|
||||
import { resolveRoutePath, useRouter, withBase } from 'vuepress/client'
|
||||
import { EXTERNAL_URL_RE } from '../utils/index.js'
|
||||
import IconExternalLink from './icons/IconExternalLink.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
@ -18,12 +18,19 @@ const tag = computed(() => props.tag ?? (props.href ? 'a' : 'span'))
|
||||
const isExternal = computed(
|
||||
() => props.href && EXTERNAL_URL_RE.test(props.href),
|
||||
)
|
||||
const link = computed(() => {
|
||||
if (!props.href)
|
||||
return undefined
|
||||
if (isExternal.value)
|
||||
return props.href
|
||||
return withBase(resolveRoutePath(props.href))
|
||||
})
|
||||
|
||||
function linkTo(e: Event) {
|
||||
if (!isExternal.value) {
|
||||
e.preventDefault()
|
||||
if (props.href)
|
||||
router.push({ path: props.href })
|
||||
if (link.value)
|
||||
router.push({ path: link.value })
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -32,8 +39,8 @@ function linkTo(e: Event) {
|
||||
<Component
|
||||
:is="tag"
|
||||
class="auto-link"
|
||||
:class="{ link: href }"
|
||||
:href="href ? normalizeLink(href) : undefined"
|
||||
:class="{ link }"
|
||||
:href="link"
|
||||
:target="target ?? (isExternal ? '_blank' : undefined)"
|
||||
:rel="rel ?? (isExternal ? 'noreferrer' : undefined)"
|
||||
@click="linkTo($event)"
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
export * from './darkMode.js'
|
||||
export * from './useScrollPromise.js'
|
||||
export * from './themeData.js'
|
||||
export * from './useResolveRouteWithRedirect.js'
|
||||
export * from './useNavLink.js'
|
||||
export * from './sidebar.js'
|
||||
export * from './aside.js'
|
||||
export * from './page.js'
|
||||
|
||||
22
theme/src/client/composables/useNavLink.ts
Normal file
22
theme/src/client/composables/useNavLink.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import { resolveRoute } from 'vuepress/client'
|
||||
import type { NavItemWithLink } from '../../shared/index.js'
|
||||
|
||||
/**
|
||||
* Resolve NavLink props from string
|
||||
*
|
||||
* @example
|
||||
* - Input: '/README.md'
|
||||
* - Output: { text: 'Home', link: '/' }
|
||||
*/
|
||||
export function useNavLink(config: string): NavItemWithLink {
|
||||
const { notFound, meta, path } = resolveRoute<{
|
||||
title?: string
|
||||
}>(config)
|
||||
|
||||
return notFound
|
||||
? { text: path, link: path }
|
||||
: {
|
||||
text: meta.title || path,
|
||||
link: path,
|
||||
}
|
||||
}
|
||||
@ -1,45 +0,0 @@
|
||||
import { isFunction, isString } from 'vuepress/shared'
|
||||
import { useRouter } from 'vuepress/client'
|
||||
import type { Router } from 'vuepress/client'
|
||||
import type { NavItemWithLink } from '../../shared/index.js'
|
||||
|
||||
/**
|
||||
* Resolve a route with redirection
|
||||
*/
|
||||
export function useResolveRouteWithRedirect(...args: Parameters<Router['resolve']>): ReturnType<Router['resolve']> {
|
||||
const router = useRouter()
|
||||
const route = router.resolve(...args)
|
||||
const lastMatched = route.matched[route.matched.length - 1]
|
||||
if (!lastMatched?.redirect)
|
||||
return route
|
||||
|
||||
const { redirect } = lastMatched
|
||||
const resolvedRedirect = isFunction(redirect) ? redirect(route) : redirect
|
||||
const resolvedRedirectObj = isString(resolvedRedirect)
|
||||
? { path: resolvedRedirect }
|
||||
: resolvedRedirect
|
||||
return useResolveRouteWithRedirect({
|
||||
hash: route.hash,
|
||||
query: route.query,
|
||||
params: route.params,
|
||||
...resolvedRedirectObj,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve NavLink props from string
|
||||
*
|
||||
* @example
|
||||
* - Input: '/README.md'
|
||||
* - Output: { text: 'Home', link: '/' }
|
||||
*/
|
||||
export function useNavLink(item: string): NavItemWithLink {
|
||||
// the route path of vue-router is url-encoded, and we expect users are using
|
||||
// non-url-encoded string in theme config, so we need to url-encode it first to
|
||||
// resolve the route correctly
|
||||
const resolved = useResolveRouteWithRedirect(encodeURI(item))
|
||||
return {
|
||||
text: (resolved.meta as any).title || item,
|
||||
link: resolved.name === '404' ? item : resolved.fullPath,
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user