119 lines
3.0 KiB
Vue
119 lines
3.0 KiB
Vue
<script setup lang="ts">
|
||
import type { ContentNavigationItem } from '@nuxt/content'
|
||
import { findPageHeadline } from '#ui-pro/utils/content'
|
||
|
||
// definePageMeta({
|
||
// layout: 'docs'
|
||
// })
|
||
|
||
const route = useRoute()
|
||
const appConfig = useAppConfig()
|
||
const navigation = inject<Ref<ContentNavigationItem[]>>('navigation')
|
||
|
||
// 获取主题系统的字号设置
|
||
const { selectedFontSize } = useTheme()
|
||
|
||
// 计算页面内容的字号类
|
||
const pageFontSizeClass = computed(() => {
|
||
return `text-${selectedFontSize.value}`
|
||
})
|
||
|
||
// 根据路由参数构建内容路径
|
||
const path = computed(() => {
|
||
const slug = route.params.slug
|
||
|
||
// 处理 slug 参数
|
||
if (!slug) {
|
||
return '/' // 如果没有 slug,返回根路径
|
||
}
|
||
|
||
const pathValue = Array.isArray(slug) ? slug.join('/') : slug
|
||
|
||
// 确保路径以 / 开头,不以 / 结尾,并过滤掉文件扩展名
|
||
const normalizedPath = `/${pathValue}`
|
||
.replace(/\/+$/, '') // 使用 /+ 匹配多个连续的斜杠
|
||
.replace(/\.(md|markdown|txt|html|vue)$/i, '') // 过滤掉常见的文件扩展名
|
||
|
||
return normalizedPath
|
||
})
|
||
|
||
// URL 解码并验证路径
|
||
const queryPath = computed(() => {
|
||
try {
|
||
return decodeURIComponent(path.value)
|
||
} catch (error) {
|
||
console.error('URL decode error:', error)
|
||
return path.value // 如果解码失败,返回原始路径
|
||
}
|
||
})
|
||
|
||
const { data: page } = await useAsyncData(
|
||
`page-${route.path}`, // 使用更具体的 key
|
||
() => queryCollection('docs').path(queryPath.value).first(),
|
||
{
|
||
default: () => null // 提供默认值
|
||
}
|
||
)
|
||
|
||
if (!page.value) {
|
||
throw createError({
|
||
statusCode: 404,
|
||
statusMessage: '文档不存在',
|
||
message: `当前页面不存在,请您检查路径是否正确: ${queryPath.value}`,
|
||
fatal: true
|
||
})
|
||
}
|
||
|
||
|
||
// 复制状态
|
||
const isCopied = ref(false)
|
||
|
||
// 复制全文功能
|
||
const copyFullText = async () => {
|
||
if (!page.value?.rawbody) {
|
||
return
|
||
}
|
||
|
||
try {
|
||
await navigator.clipboard.writeText(page.value.rawbody)
|
||
// 设置复制成功状态
|
||
isCopied.value = true
|
||
// 2秒后重置状态
|
||
setTimeout(() => {
|
||
isCopied.value = false
|
||
}, 2000)
|
||
} catch (error) {
|
||
console.error('复制失败:', error)
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<template>
|
||
<UPage>
|
||
<!-- 复制按钮 -->
|
||
<div class="mb-4 flex justify-start">
|
||
<UButton
|
||
@click="copyFullText"
|
||
:icon="isCopied ? 'lucide-check' : 'lucide-copy'"
|
||
variant="solid"
|
||
size="sm"
|
||
>
|
||
{{ isCopied ? '已复制' : '复制全文' }}
|
||
</UButton>
|
||
</div>
|
||
|
||
<!-- 原始内容显示区域 -->
|
||
<div
|
||
class="bg-gray-50 dark:bg-gray-900 rounded-lg p-4 overflow-auto"
|
||
style="user-select: text; -webkit-user-select: text; -moz-user-select: text; -ms-user-select: text;"
|
||
>
|
||
<pre
|
||
class="whitespace-pre-wrap break-words text-sm"
|
||
style="user-select: text; -webkit-user-select: text; -moz-user-select: text; -ms-user-select: text;"
|
||
>
|
||
{{ page?.rawbody }}
|
||
</pre>
|
||
</div>
|
||
</UPage>
|
||
</template>
|