修改页面布局大修改
This commit is contained in:
197
app/pages/blog/[...slug].vue
Normal file
197
app/pages/blog/[...slug].vue
Normal file
@@ -0,0 +1,197 @@
|
||||
<script setup lang="ts">
|
||||
import type { ContentNavigationItem } from '@nuxt/content'
|
||||
import { findPageHeadline } from '#ui-pro/utils/content'
|
||||
|
||||
definePageMeta({
|
||||
layout: 'blog'
|
||||
})
|
||||
|
||||
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(() => route.path)
|
||||
|
||||
// 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('blog').path(decodeURIComponent(path.value)).first(),
|
||||
{
|
||||
default: () => null // 提供默认值
|
||||
}
|
||||
)
|
||||
|
||||
if (!page.value) {
|
||||
throw createError({
|
||||
statusCode: 404,
|
||||
statusMessage: '文档不存在',
|
||||
message: `当前页面不存在,请您检查路径是否正确: ${queryPath.value}`,
|
||||
fatal: true
|
||||
})
|
||||
}
|
||||
|
||||
const { data: surround } = await useAsyncData(`${route.path}-surround`, () => {
|
||||
return queryCollectionItemSurroundings('docs', route.path, {
|
||||
fields: ['description']
|
||||
})
|
||||
})
|
||||
|
||||
const title = page.value.seo?.title || page.value.title
|
||||
const description = page.value.seo?.description || page.value.description
|
||||
|
||||
useSeoMeta({
|
||||
title,
|
||||
ogTitle: title,
|
||||
description,
|
||||
ogDescription: description
|
||||
})
|
||||
|
||||
const headline = computed(() => findPageHeadline(navigation?.value, page.value))
|
||||
|
||||
defineOgImageComponent('Docs', {
|
||||
headline: headline.value
|
||||
})
|
||||
|
||||
const editLink = computed(() => {
|
||||
if (!appConfig.github) {
|
||||
return
|
||||
}
|
||||
|
||||
return [
|
||||
appConfig.github.url,
|
||||
'edit',
|
||||
appConfig.github.branch,
|
||||
appConfig.github.rootDir,
|
||||
'content',
|
||||
`${page.value?.stem}.${page.value?.extension}`
|
||||
].filter(Boolean).join('/')
|
||||
})
|
||||
|
||||
const links = computed(() => {
|
||||
const links = []
|
||||
if (appConfig.toc?.bottom?.edit) {
|
||||
links.push({
|
||||
icon: 'lucide-external-link',
|
||||
label: '编辑页面',
|
||||
to: `${appConfig.toc.bottom.edit}/${page?.value?.stem}.${page?.value?.extension}`,
|
||||
target: '_blank'
|
||||
})
|
||||
}
|
||||
|
||||
return [...links, ...(appConfig.toc?.bottom?.links || [])].filter(Boolean)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UPage
|
||||
v-if="page"
|
||||
:class="pageFontSizeClass"
|
||||
>
|
||||
<UPageHeader
|
||||
:title="page.title"
|
||||
:description="page.description"
|
||||
:headline="headline"
|
||||
:ui="{
|
||||
wrapper: 'flex-row items-center flex-wrap justify-between '
|
||||
}"
|
||||
>
|
||||
<template #links>
|
||||
<UButton
|
||||
v-for="(link, index) in page.links"
|
||||
:key="index"
|
||||
size="sm"
|
||||
v-bind="link"
|
||||
/>
|
||||
|
||||
<DocsPageHeaderLinks />
|
||||
</template>
|
||||
</UPageHeader>
|
||||
|
||||
<UPageBody>
|
||||
<ContentRenderer
|
||||
v-if="page"
|
||||
:value="page"
|
||||
/>
|
||||
|
||||
<USeparator>
|
||||
<div
|
||||
v-if="editLink"
|
||||
class="flex items-center gap-2 text-sm text-muted"
|
||||
>
|
||||
<UButton
|
||||
variant="link"
|
||||
color="neutral"
|
||||
:to="editLink"
|
||||
target="_blank"
|
||||
icon="lucide-pen"
|
||||
:ui="{ leadingIcon: 'size-4' }"
|
||||
>
|
||||
编辑页面
|
||||
</UButton>
|
||||
or
|
||||
<UButton
|
||||
variant="link"
|
||||
color="neutral"
|
||||
:to="`${appConfig.github.url}/issues/new/choose`"
|
||||
target="_blank"
|
||||
icon="lucide-alert-circle"
|
||||
:ui="{ leadingIcon: 'size-4' }"
|
||||
>
|
||||
提交问题
|
||||
</UButton>
|
||||
</div>
|
||||
</USeparator>
|
||||
<UContentSurround :surround="surround" />
|
||||
</UPageBody>
|
||||
|
||||
<template
|
||||
v-if="page?.body?.toc?.links?.length"
|
||||
#right
|
||||
>
|
||||
<div class="fixed top-24 right-15 w-auto">
|
||||
<UContentToc
|
||||
:title="appConfig.toc?.title"
|
||||
:links="page.body?.toc?.links"
|
||||
>
|
||||
<template
|
||||
v-if="appConfig.toc?.bottom"
|
||||
#bottom
|
||||
>
|
||||
<div
|
||||
class="hidden lg:block space-y-6 "
|
||||
:class="{ '!mt-5': page.body?.toc?.links?.length }"
|
||||
>
|
||||
<USeparator
|
||||
v-if="page.body?.toc?.links?.length"
|
||||
type="dashed"
|
||||
/>
|
||||
|
||||
<UPageLinks
|
||||
:title="appConfig.toc.bottom.title"
|
||||
:links="links"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</UContentToc>
|
||||
</div>
|
||||
</template>
|
||||
</UPage>
|
||||
</template>
|
24
app/pages/blog/index.vue
Normal file
24
app/pages/blog/index.vue
Normal file
@@ -0,0 +1,24 @@
|
||||
<script setup lang="ts">
|
||||
definePageMeta({
|
||||
layout: 'blog'
|
||||
})
|
||||
|
||||
const title = 'Estel Blog'
|
||||
const description = 'Estel Blog'
|
||||
|
||||
useSeoMeta({
|
||||
titleTemplate: '',
|
||||
title,
|
||||
ogTitle: title,
|
||||
description,
|
||||
ogDescription: description,
|
||||
ogImage: 'https://assets.hub.nuxt.com/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1cmwiOiJodHRwczovL2RvY3MtdGVtcGxhdGUubnV4dC5kZXYiLCJpYXQiOjE3Mzk0NjM0MTd9.ltVAqPgKG38O01X1zl6MXfrJc55nf9OewXNFjpZ_2JY.jpg?theme=light',
|
||||
twitterImage: 'https://assets.hub.nuxt.com/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1cmwiOiJodHRwczovL2RvY3MtdGVtcGxhdGUubnV4dC5kZXYiLCJpYXQiOjE3Mzk0NjM0MTd9.ltVAqPgKG38O01X1zl6MXfrJc55nf9OewXNFjpZ_2JY.jpg?theme=light'
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<BlogIndexBlog />
|
||||
</div>
|
||||
</template>
|
Reference in New Issue
Block a user