e4757446cf
mirror-to-gitee / mirror (push) Successful in 4s
用户反馈 /projects/(项目列表)页底部的品牌/联系/版权区应该去掉。 背景:这几个文件此前一直未提交——远端仓库其实没有页脚, PortalFooter.vue 只存在于本地,HEAD 版 index.ts 也没引用它。 所以本次把页脚整套补齐,再叠加「按页面决定是否展示」的逻辑。 新增/改动 - .vitepress/theme/components/PortalFooter.vue(新增,274 行) 品牌区 + 产品体系/文档资源/关于我们/联系我们四栏 + 二维码浮层 + 版权条 - .vitepress/theme/styles/portal.css:补入全部 .pf-foot-* 样式(508 行) 只搬运页脚相关规则,不夹带工作区里其它未提交的样式改动 - .vitepress/theme/index.ts:挂载页脚 + 页面级显隐判定 - pages/projects/index.md:frontmatter 加 footer: false 页脚显隐判定(isDocPage) 「文档型页面不挂页脚」——这类页面有左侧目录树、右侧本页目录、 底部上一页/下一页翻页,读者正在阅读流里,450px 的品牌收尾区是纯噪音。 命中任一条件即隐藏: 1) 路径 /projects/<id>/manual/... 2) frontmatter 有 sidebar / outline / aside 3) frontmatter 显式 footer: false frontmatter 的 footer 可双向覆盖(这解决了 /projects/ 的困境): 该页有 outline: deep,按上面的规则本会被判成文档页而隐藏页脚, 但它本质是「浏览页」,需要显式 footer: false 才符合预期。 同理 footer: true 可强制显示。 验证(干净 clone 构建后实测) - /projects/ 无页脚(footer=false,无版权条) - / 有页脚(453px,渐变背景正常) - 文档页(详情/对比/快速开始/手册)均无页脚 - 自定义整页(关于/联系/演示/官方文档)均有页脚
91 lines
3.5 KiB
TypeScript
91 lines
3.5 KiB
TypeScript
import DefaultTheme from 'vitepress/theme'
|
|
import type { Theme } from 'vitepress'
|
|
import { h, watch, nextTick, computed } from 'vue'
|
|
import { useData, useRoute } from 'vitepress'
|
|
|
|
import ProjectList from './components/ProjectList.vue'
|
|
import HomePage from './components/HomePage.vue'
|
|
import CapabilityTabs from './components/CapabilityTabs.vue'
|
|
import FeatureGrid from './components/FeatureGrid.vue'
|
|
import ScreenshotPreview from './components/ScreenshotPreview.vue'
|
|
import PortalFooter from './components/PortalFooter.vue'
|
|
|
|
import { setupNavAnchorHighlight, applyNavAnchorHighlight } from './nav-anchor'
|
|
|
|
import './styles/portal.css'
|
|
|
|
/**
|
|
* 首页用 layout: page 承载自定义整页排版,
|
|
* 这里给它套一层 .portal-page,把默认窄栏与 padding 去掉。
|
|
* 同时接管导航栏锚点项的高亮(VitePress 默认只认 path,不认 hash)。
|
|
*/
|
|
const PortalLayout = () => {
|
|
const { frontmatter } = useData()
|
|
const route = useRoute()
|
|
|
|
const isPortal = frontmatter.value.layout === 'page'
|
|
|
|
/**
|
|
* 是否隐藏整站页脚。
|
|
*
|
|
* 判定原则:**文档型页面不挂页脚**。
|
|
* 这类页面有左侧目录树、右侧本页目录、底部上一页/下一页翻页,
|
|
* 读者正处在阅读流里,页脚那 450px 的品牌/联系/版权是纯噪音,
|
|
* 还会和翻页按钮挤在一起。
|
|
*
|
|
* 覆盖三种情况:
|
|
* 1) 路径命中项目手册 `/projects/<id>/manual/...`
|
|
* 2) frontmatter 写了 `sidebar` / `outline` / `aside`(文档页标记)
|
|
* 3) frontmatter 显式 `footer: false`
|
|
*
|
|
* frontmatter 的 `footer` 可双向覆盖:
|
|
* footer: false → 强制隐藏(如清单页 /projects/:有 outline 但本质是浏览页)
|
|
* footer: true → 强制显示
|
|
*
|
|
* 自定义整页(layout: page,如首页/关于/演示/官方文档)不在此列,
|
|
* 它们有完整的品牌收尾节奏,页脚保留。
|
|
*/
|
|
const isManualPath = computed(() => /^\/projects\/[^/]+\/manual(\/|$)/.test(route.path))
|
|
const isDocPage = computed(() => {
|
|
const fm = frontmatter.value as Record<string, unknown>
|
|
if (fm.layout === 'page' || fm.layout === 'home') return false
|
|
if (fm.footer === false) return true
|
|
if (fm.footer === true) return false
|
|
const hasDocMarks =
|
|
fm.sidebar !== undefined || fm.outline !== undefined || fm.aside !== undefined
|
|
return isManualPath.value || hasDocMarks
|
|
})
|
|
|
|
/**
|
|
* Layout 是函数式组件,onMounted 在这里不生效(Vue 会告警),
|
|
* 因此直接在渲染期间调度:等 DOM 落地后跑一次,再靠 MutationObserver 兜住后续变化。
|
|
*/
|
|
if (typeof window !== 'undefined') {
|
|
nextTick(() => setupNavAnchorHighlight())
|
|
}
|
|
|
|
// SPA 路由切换不触发 hashchange,这里补一次
|
|
watch(
|
|
() => [route.path, route.hash],
|
|
() => nextTick(() => applyNavAnchorHighlight())
|
|
)
|
|
|
|
return h('div', { class: isPortal ? 'portal-page' : '' }, h(DefaultTheme.Layout, null, {
|
|
// 自定义整站页脚(品牌 + 多栏链接 + 联系方式 + 版权条)
|
|
// 文档型页面一律不挂(见 isDocPage 判定)
|
|
'layout-bottom': isDocPage.value ? undefined : () => h(PortalFooter),
|
|
}))
|
|
}
|
|
|
|
export default {
|
|
extends: DefaultTheme,
|
|
Layout: PortalLayout,
|
|
enhanceApp({ app }) {
|
|
app.component('ProjectList', ProjectList)
|
|
app.component('HomePage', HomePage)
|
|
app.component('CapabilityTabs', CapabilityTabs)
|
|
app.component('FeatureGrid', FeatureGrid)
|
|
app.component('ScreenshotPreview', ScreenshotPreview)
|
|
},
|
|
} satisfies Theme
|