外观
VuePress Plume 首页归档化与导航精简实践
约 1666 字大约 6 分钟
2026-06-09
生成说明:本文由 OpenAI Codex(基于 GPT-5 的 AI 编程助手)根据本次站点改造会话生成。AI 生成提示为:“根据本次会话生成一篇博文,需要注明 AI 生成提示,文章内容科学严谨。”生成时间为 2026/06/09。
这次改造的目标很明确:让博客首页直接呈现文章归档列表,而不是先进入首页再跳转到归档页;同时清理导航栏、面包屑、无用聚合页和站点图标,使页面结构更直接,用户路径更短。
从工程角度看,这不是简单地“把链接换一下”。首页、集合页、导航栏、主题外观开关、favicon 和构建产物之间存在依赖关系。如果只修改某一个入口,很容易留下重复页面、错误标题、不可见但仍生成的页面,或者视觉上存在但交互不稳定的控件。
1. 问题界定
原先首页通过 docs/README.md 做跳转,将访问 / 的用户重定向到 /blog/archives/。这种做法能达到“默认显示归档”的表面效果,但有三个问题:
- 首页不是实际内容页,而是跳转页,首屏体验依赖客户端跳转。
- 页面标题和路径仍与“归档页”绑定,不符合“首页就是归档列表”的语义。
- 主题仍会生成
/blog/archives/、/blog/categories/、/blog/等聚合页,容易形成重复入口。
因此,本次改造采用的原则是:让 / 成为真正的归档列表页,而不是归档页的代理入口。
2. 首页归档化
首页 frontmatter 被改为自定义页面布局:
---
title: WORTHY BLOG
pageLayout: HomeArchives
pageClass: home-archives-page
description: WORTHY BLOG
---HomeArchives 组件从 usePostsData() 获取博客文章数据,并按文章创建年份分组。这个实现没有依赖客户端路由跳转,也没有复用 /blog/archives/ 路径,因此首页语义更加清晰。
核心逻辑可以概括为:
const groups = new Map<string, ShortPost[]>()
for (const post of postsData.value['/blog/'] || []) {
const createTime = post.createTime?.split(/\s|T/)[0] || ''
const year = createTime.split('/')[0]
const list = groups.get(year) || []
list.push({
title: post.title,
path: post.path,
createTime: createTime.slice(year.length + 1).replace(/\//g, '-'),
})
groups.set(year, list)
}这里的关键点是:文章数据仍由 VuePress Plume 的 collection 系统生成,自定义组件只负责展示,不重新扫描文件系统,也不手动维护文章列表。这能减少数据源不一致的风险。
3. 导航与正文结构调整
为了让首页更像一个纯粹的文章入口,本次移除了顶部导航里的“首页”按钮。原因很简单:用户已经位于首页时,再显示一个指向首页的按钮并没有实际导航价值。
正文页中的面包屑导航也被隐藏。对于当前博客结构而言,文章页的主要信息已经由标题、创建时间、阅读时间和正文承载,面包屑中的“首页 / Blog / 分类 / 标题”会增加视觉噪声。隐藏方式保持在样式层:
.vp-breadcrumb {
display: none;
}这类改动不会删除文章页面本身,也不会影响永久链接,只改变页面上的导航呈现。
4. 黑白模式入口
VuePress Plume 在中等宽度视口下默认通过右上角的 extra navigation 菜单承载外观切换。实际使用时,这意味着切换黑白模式需要先打开三点菜单,再点击开关。
本次改造将外观开关直接显示在导航栏右上角,并隐藏三点菜单:
@media (min-width: 768px) {
.vp-navbar .vp-navbar-appearance {
display: flex !important;
align-items: center;
}
.vp-navbar .vp-navbar-extra {
display: none !important;
}
}这个方案保留了主题原生的 VPSwitchAppearance 组件,因此没有额外引入状态管理,也没有重复实现黑白模式逻辑。验证时确认开关可以在 light 与 dark 之间切换,并能恢复原状态。
5. 精简自动聚合页
当首页已经承担归档列表职责后,主题自动生成的 /blog/archives/ 就不再必要。与此同时,当前站点也没有启用标签页和分类页展示需求。
最终 collection 配置被收敛为:
const blog = defineCollection({
type: 'post',
dir: 'blog',
title: 'Blog',
link: '/blog/',
postList: false,
tags: false,
archives: false,
categories: false,
})这一步的结果可以量化:构建页数从 168 降到 165,减少的正是 /blog/、/blog/archives/、/blog/categories/ 三个无用聚合页。文章页仍正常生成,文章数据也仍可供首页组件读取。
6. Logo 与 favicon
最后,站点标识被替换为 SVG 资源:
- 导航栏 logo:
/img/logo.svg - 浏览器 favicon:
/img/favicon.svg
相比原来的 PNG,SVG 在小尺寸和高分辨率屏幕下更稳定,文件也便于直接维护。配置分别位于主题配置和站点 head 中:
logo: '/img/logo.svg'['link', { rel: 'icon', type: 'image/svg+xml', href: '/img/favicon.svg' }]7. 验证结果
本次改造完成后进行了以下验证:
- 执行
pnpm docs:build,构建成功。 - 首页
/不再跳转,直接显示按年份分组的文章列表。 - 页面标题不再包含“归档”字样。
- 顶部导航不再显示“首页”按钮。
- 文章正文不再显示面包屑导航。
- 右上角三点菜单隐藏,黑白模式开关直接可用。
/blog/、/blog/archives/、/blog/categories/不再生成。- 导航栏 logo 和 favicon 均指向新的 SVG 文件。
这些验证覆盖了路由、构建产物、DOM 可见状态和基础交互,能够说明本次修改不是单纯的视觉覆盖,而是对页面入口和生成逻辑做了较完整的收敛。
8. 小结
这次改造的核心不是“把归档页搬到首页”,而是重新定义首页职责:/ 应该是用户进入博客后的主要内容入口,而不是通往另一个页面的过渡层。
从维护角度看,较理想的状态是:入口少、路径清晰、生成页面可解释、交互不绕路。首页直接展示归档列表后,博客的访问路径变短了;关闭无用聚合页后,构建产物更干净了;将黑白模式开关直接暴露后,常用操作也更符合直觉。
这类优化通常不需要复杂技术,但需要把“页面看到什么”和“构建实际生成什么”同时考虑清楚。否则,页面表面上变简洁了,代码和路由里却可能还留着许多旧入口。