feat(theme): 新增 useLink 组合式 API

This commit is contained in:
pengzhanbo 2024-06-24 00:09:11 +08:00
parent 7c8a1084fe
commit f792bf6cc7
4 changed files with 46 additions and 29 deletions

View File

@ -1,7 +1,7 @@
<script setup lang="ts">
import { computed } from 'vue'
import { resolveRouteFullPath, useRouter, withBase } from 'vuepress/client'
import { isLinkExternal } from 'vuepress/shared'
import { computed, toRef } from 'vue'
import { useRouter, withBase } from 'vuepress/client'
import { useLink } from '../composables/link.js'
interface Props {
tag?: string
@ -20,24 +20,13 @@ const props = withDefaults(defineProps<Props>(), {
target: undefined,
rel: undefined,
})
const router = useRouter()
const isExternal = computed(
() => props.href && isLinkExternal(props.href),
)
const component = computed(() => {
return props.tag || props.href ? 'a' : 'button'
})
const link = computed(() => {
if (!props.href)
return undefined
if (isExternal.value)
return props.href
return resolveRouteFullPath(props.href)
})
const { link, isExternal } = useLink(toRef(props, 'href'), toRef(props, 'target'))
function linkTo(e: Event) {
if (!isExternal.value) {

View File

@ -1,7 +1,7 @@
<script lang="ts" setup>
import { computed } from 'vue'
import { resolveRouteFullPath, useRoute, useRouter, withBase } from 'vuepress/client'
import { isLinkExternal } from '@vuepress/helper/client'
import { computed, toRef } from 'vue'
import { useRouter, withBase } from 'vuepress/client'
import { useLink } from '../composables/link.js'
const props = defineProps<{
tag?: string
@ -12,19 +12,10 @@ const props = defineProps<{
}>()
const router = useRouter()
const route = useRoute()
const tag = computed(() => props.tag ?? (props.href ? 'a' : 'span'))
const isExternal = computed(
() => (props.href && isLinkExternal(props.href)) || props.target === '_blank',
)
const link = computed(() => {
if (!props.href)
return undefined
if (isExternal.value)
return props.href
return resolveRouteFullPath(props.href, route.path)
})
const { link, isExternal } = useLink(toRef(props, 'href'), toRef(props, 'target'))
function linkTo(e: Event) {
if (!isExternal.value) {

View File

@ -19,6 +19,7 @@ export * from './blog-tags.js'
export * from './blog-archives.js'
export * from './tag-colors.js'
export * from './link.js'
export * from './locale.js'
export * from './route-query.js'
export * from './watermark.js'

View File

@ -0,0 +1,36 @@
import { isLinkExternal } from '@vuepress/helper/client'
import { resolveRouteFullPath, useRoute } from 'vuepress/client'
import { type MaybeRefOrGetter, computed, toValue } from 'vue'
import { useData } from './data.js'
const SEARCH_RE = /\.md(?:(?:#|\?).*)?$/
export function useLink(
href: MaybeRefOrGetter<string | undefined>,
target?: MaybeRefOrGetter<string | undefined>,
) {
const route = useRoute()
const { page } = useData()
const isExternal = computed(
() => {
const link = toValue(href)
const rawTarget = toValue(target)
return (link && isLinkExternal(link)) || rawTarget === '_blank'
},
)
const link = computed(() => {
const link = toValue(href)
if (!link)
return undefined
if (isExternal.value)
return link
const currentPath = link.startsWith('./') && SEARCH_RE.test(link)
? `/${page.value.filePathRelative!}`
: route.path
return resolveRouteFullPath(link, currentPath)
})
return { isExternal, link }
}