项目结构分析
VuePress 是以 Markdown 为中心的。你项目中的每一个 Markdown 文件都是一个单独的页面。
默认情况下,页面的路由路径是根据你的 Markdown 文件的相对路径决定的。
由于你的项目是通过创建助手生成的,那么你会得到以下文件结构:
项目结构
ZH-Kinger/
├── .github/ # GitHub Actions 自动化部署配置(可选)
├── node_modules/ # [核心] 项目依赖包(VuePress 实体就在这里)
├── src/ # [核心] 你的源文件目录
│ ├── .vuepress/ # [核心] VuePress 特有配置文件夹
│ │ ├── public/ # 静态资源(本地图片、图标、favicon)
│ │ ├── config.ts # 站点总配置文件(基础路径、语言、head等)
│ │ ├── navbar.ts # 顶部导航栏配置
│ │ ├── sidebar.ts # 侧边栏配置
│ │ └── theme.ts # 主题深度配置(颜色、插件、博主信息)
│ ├── demo/ # 示例文章文件夹(后续可以删除)
│ ├── posts/ # 你的博文存放目录
│ │ ├── apple/ # 子分类文件夹
│ │ └── nginx.md # 具体文章文件
│ └── README.md # 博客主页内容
├── package.json # [核心] 项目脚本(npm run)和版本信息
├── tsconfig.json # TypeScript 配置文件
└── package-lock.json # 依赖锁定文件
你的 Markdown 文件对应的路由路径为:
| 相对路径 | 路由路径 |
|---|---|
/README.md |
/ |
/demo/README.md |
/demo/ |
/demo/page.md |
/demo/page.html |
README.md 是特例,在 Markdown 中,按照约定俗成,它会作为所在文件夹的主页。所以在渲染为网页时,它的对应路径为网页中的主页路径 index.html。
这应该很好理解。
配置文件介绍
src/README.md(主页配置文件)
---
home: true
layout: Blog
title: ZH-Kinger #标题
heroImage: /assets/images/logo.png #头像图标
bgImage: /assets/images/cover4.jpg #背景图
heroText: 王梓涵
heroFullScreen: true
tagline: Without Mercy
projects:
- icon: folder-open
name: 项目名称
desc: 项目详细描述
link: https://你的项目链接
- icon: link
name: 链接名称
desc: 链接详细描述
link: https://链接地址
- icon: book
name: 书籍名称
desc: 书籍详细描述
link: https://你的书籍链接
- icon: newspaper
name: 文章名称
desc: 文章详细描述
link: https://你的文章链接
- icon: user-group
name: 伙伴名称
desc: 伙伴详细介绍
link: https://你的伙伴链接
- icon: https://theme-hope-assets.vuejs.press/logo.svg
name: 自定义项目
desc: 自定义详细介绍
link: https://你的自定义链接
footer: 自定义你的页脚文字
---
这是一个博客主页的案例。
要使用此布局,你应该在页面前端设置 `layout: Blog` 和 `home: true`。
相关配置文档请见 [博客主页](https://theme-hope.vuejs.press/zh/guide/blog/home.html)。
配置项功能解析
1. 基础布局与身份定义
**home: true**: 告诉 VuePress 这不是一篇普通文章,而是一个特殊的首页。**layout: Blog**: 指定使用“博客布局”。这会启用大图背景、博主信息卡片和文章列表。**icon: house**: 在浏览器标签页或路径导航中显示的首页图标。**title: ZH-Kinger**: 网页的标题,显示在浏览器最上方的标签栏。
2. 视觉门面(Hero 部分)
这部分控制首页中间那块巨大的背景和文字。
**heroImage**: 你的 Logo。/assets/images/logo.png指向的是项目里public文件夹下的图片。**bgImage**: 首页的全屏背景图。建议找一张高清、不刺眼的图。**heroText**: 你的大名,会以最醒目的字体显示在屏幕中间。**heroFullScreen: true**: 背景图是否撑满整个屏幕。如果设为false,背景图会变矮。**tagline**: 你的座右铭或简短自我介绍,显示在大名下方。
image.png
3. 项目展示栏(Projects)
这是一个非常有用的展示区域,可以链接到你的 GitHub、作品集或推荐资源。
**projects**: 一个列表数组。**icon**: 图标。支持图标库名字(如folder-open)或图片链接。**name**: 项目的小标题。**desc**: 对项目的简短描述(一行字左右)。**link**: 点击后跳转到的地址。
💡 建议:如果你目前还没有这么多项目,可以先删掉多余的部分,只留下一两个重要的链接。

4. 底部信息(Footer)
**footer**: 页面最底部的版权信息或备案号。
页面元素配置
config.ts(网页配置文件)
import { defineUserConfig } from "vuepress";
import theme from "./theme.js";
export default defineUserConfig({
base: "/blog/", #默认是/
lang: "zh-CN",
title: "博客blog",
description: "vuepress-theme-hope 的博客blog",
theme,
// 添加以下 head 配置来解决语雀图片不显示的问题
head: [
[
"meta",
{ name: "referrer", content: "no-referrer" }
]
],
// 和 PWA 一起启用
// shouldPrefetch: false,
});
格式错误问题
刚开始进入时格式可能乱码大概率时BaseUrl的问题
构建时的默认BaseUrl是 /
我们要将它修改为/blog/
图片配置解决md文件外部链接图片加载失败问题
如何让 VuePress “直接”加载出来?
如果你坚持不想下载图片到本地,可以通过修改 VuePress 配置,告诉浏览器 “不要告诉对方我是谁”,从而绕过防盗链限制。
修改方法:
打开你的配置文件:**src/.vuepress/config.ts**(或者是 .vuepress/config.js),在 head 部分添加一行代码:
export default {
// ... 其他配置
head: [
// 核心代码:强制浏览器不发送 Referer 信息
['meta', { name: 'referrer', content: 'no-referrer' }]
],
// ...
}
原理: 设置 no-referrer 后,浏览器在加载图片时会隐藏你的网站信息,语雀服务器就会像你手动输入链接一样,认为这是合法请求,图片就能直接显示了。
navbar.ts(顶栏组件)
import { navbar } from "vuepress-theme-hope";
export default navbar([
"/",
"/demo/",
{
text: "博文",
icon: "pen-to-square",
prefix: "/posts/",
children: [
{
text: "苹果",
icon: "pen-to-square",
prefix: "apple/",
children: [
{ text: "苹果1", icon: "pen-to-square", link: "1" },
{ text: "苹果2", icon: "pen-to-square", link: "2" },
"3",
"4",
],
},
{
text: "香蕉",
icon: "pen-to-square",
prefix: "banana/",
children: [
{
text: "香蕉 1",
icon: "pen-to-square",
link: "1",
},
{
text: "香蕉 2",
icon: "pen-to-square",
link: "2",
},
"3",
"4",
],
},
{ text: "樱桃", icon: "pen-to-square", link: "cherry" },
{ text: "火龙果", icon: "pen-to-square", link: "dragonfruit" },
"服务器资源预警平台",
"web开发教程",
],
},
{
text: "V2 文档",
icon: "book",
link: "https://theme-hope.vuejs.press/zh/",
},
]);
sidebar.ts(侧栏/下拉栏)
1. 核心功能
- 文章导航:展示当前栏目下的所有文章标题,方便用户快速跳转。
- 目录分组:可以将文章按照文件夹或主题进行分组(如:Python、Nginx、生活随笔)。
- 多级折叠:支持创建多级嵌套菜单,点击父级可以展开或收起子项目。
- 自动/手动生成:既可以让 VuePress 自动扫描文件夹生成目录,也可以由你手动指定显示的顺序。
import { sidebar } from "vuepress-theme-hope";
export default sidebar({
"/": [
"",
{
text: "如何使用",
icon: "laptop-code",
prefix: "demo/",
link: "demo/",
children: "structure",
},
{
text: "文章",
icon: "book",
prefix: "posts/",
children: "structure", #自动获取你的md文件
},
"intro",
{
text: "幻灯片",
icon: "person-chalkboard",
link: "https://ecosystem.vuejs.press/zh/plugins/markdown/revealjs/demo.html",
},
],
});
theme.ts(主页面配置)
1. 核心功能配置
- 博主信息设置:配置你(author)在首页和侧边栏显示的头像(logo)、昵称(name)、座右铭以及社交媒体链接(blog如 GitHub、知乎等)。
- 博客属性开关:控制是否开启文章列表页、时间轴、分类和标签功能。
- 外观定制:设置网站的主题色、是否允许暗黑模式切换、以及页脚(Footer)的默认显示内容。
2. 插件中心(Plugins)
theme.ts 内部通常包含一个巨大的 plugins 对象,用来开启或关闭强大的内置功能:
- 搜索功能:配置搜索插件(如本地搜索或 DocSearch)。
- Markdown 增强:开启公式(LaTeX)、流程图(Mermaid)、代码块选项卡、交互式演示等。
- 组件支持:是否允许在 Markdown 里使用图标、视频播放器、PDF 预览等组件。
- 复制保护:设置代码块的一键复制功能,或者为文章添加版权后缀。
3. 配置示例拆解
你的 theme.ts 代码结构通常如下:
它与其他文件的关系
**config.ts**调用它:config.ts会导入theme.ts生成的主题配置并应用到站点。**navbar.ts**和**sidebar.ts**被它引用:为了让代码不那么臃肿,导航栏和侧边栏的细节通常写在独立文件里,然后在theme.ts中被import进来。
简单总结:如果你想修改博主头像、更改全站配色、或者开启流程图/公式支持,直接去 theme.ts 里找对应的配置项即可。
import { hopeTheme } from "vuepress-theme-hope";
import navbar from "./navbar.js";
import sidebar from "./sidebar.js";
export default hopeTheme({
hostname: "https://mister-hope.github.io",
author: {
name: "王梓涵",
url: "https://mister-hope.com",
},
logo: "/assets/images/logo.png",
repo: "vuepress-theme-hope/vuepress-theme-hope",
docsDir: "src",
// 导航栏
navbar,
// 侧边栏
sidebar,
// 页脚
footer: "默认页脚",
displayFooter: true,
// 博客相关
blog: {
description: "一个前端开发者",
intro: "/intro.html",
medias: {
Baidu: "https://example.com",
BiliBili: "https://example.com",
Bitbucket: "https://example.com",
Dingding: "https://example.com",
Discord: "https://example.com",
Dribbble: "https://example.com",
Email: "mailto:info@example.com",
Evernote: "https://example.com",
Facebook: "https://example.com",
Flipboard: "https://example.com",
Gitee: "https://example.com",
GitHub: "https://example.com",
Gitlab: "https://example.com",
Gmail: "mailto:info@example.com",
Instagram: "https://example.com",
Lark: "https://example.com",
Lines: "https://example.com",
Linkedin: "https://example.com",
Pinterest: "https://example.com",
Pocket: "https://example.com",
QQ: "https://example.com",
Qzone: "https://example.com",
Reddit: "https://example.com",
Rss: "https://example.com",
Steam: "https://example.com",
Twitter: "https://example.com",
Wechat: "https://example.com",
Weibo: "https://example.com",
Whatsapp: "https://example.com",
Youtube: "https://example.com",
Zhihu: "https://example.com",
VuePressThemeHope: {
icon: "https://theme-hope-assets.vuejs.press/logo.svg",
link: "https://theme-hope.vuejs.press",
},
},
},
// 加密配置
encrypt: {
config: {
"/demo/encrypt.html": {
hint: "Password: 1234",
password: "1234",
},
},
},
// 多语言配置
metaLocales: {
editLink: "在 GitHub 上编辑此页",
},
// 如果想要实时查看任何改变,启用它。注: 这对更新性能有很大负面影响
// hotReload: true,
// 此处开启了很多功能用于演示,你应仅保留用到的功能。
markdown: {
align: true,
attrs: true,
codeTabs: true,
component: true,
demo: true,
figure: true,
gfm: true,
imgLazyload: true,
imgSize: true,
include: true,
mark: true,
plantuml: true,
spoiler: true,
stylize: [
{
matcher: "Recommended",
replacer: ({ tag }) => {
if (tag === "em")
return {
tag: "Badge",
attrs: { type: "tip" },
content: "Recommended",
};
},
},
],
sub: true,
sup: true,
tabs: true,
tasklist: true,
vPre: true,
// 取消注释它们如果你需要 TeX 支持
// math: {
// // 启用前安装 katex
// type: "katex",
// // 或者安装 @mathjax/src
// type: "mathjax",
// },
// 如果你需要幻灯片,安装 @vuepress/plugin-revealjs 并取消下方注释
// revealjs: {
// plugins: ["highlight", "math", "search", "notes", "zoom"],
// },
// 在启用之前安装 chart.js
// chartjs: true,
// insert component easily
// 在启用之前安装 echarts
// echarts: true,
// 在启用之前安装 flowchart.ts
// flowchart: true,
// 在启用之前安装 mermaid
// mermaid: true,
// playground: {
// presets: ["ts", "vue"],
// },
// 在启用之前安装 @vue/repl
// vuePlayground: true,
// 在启用之前安装 sandpack-vue3
// sandpack: true,
},
// 在这里配置主题提供的插件
plugins: {
blog: true,
// 启用之前需安装 @waline/client
// 警告: 这是一个仅供演示的测试服务,在生产环境中请自行部署并使用自己的服务!
// comment: {
// provider: "Waline",
// serverURL: "https://waline-comment.vuejs.press",
// },
components: {
components: ["Badge", "VPCard"],
},
icon: {
prefix: "fa6-solid:",
},
// 如果你需要 PWA。安装 @vuepress/plugin-pwa 并取消下方注释
// pwa: {
// favicon: "/favicon.ico",
// cacheHTML: true,
// cacheImage: true,
// appendBase: true,
// apple: {
// icon: "/assets/icon/apple-icon-152.png",
// statusBarColor: "black",
// },
// msTile: {
// image: "/assets/icon/ms-icon-144.png",
// color: "#ffffff",
// },
// manifest: {
// icons: [
// {
// src: "/assets/icon/chrome-mask-512.png",
// sizes: "512x512",
// purpose: "maskable",
// type: "image/png",
// },
// {
// src: "/assets/icon/chrome-mask-192.png",
// sizes: "192x192",
// purpose: "maskable",
// type: "image/png",
// },
// {
// src: "/assets/icon/chrome-512.png",
// sizes: "512x512",
// type: "image/png",
// },
// {
// src: "/assets/icon/chrome-192.png",
// sizes: "192x192",
// type: "image/png",
// },
// ],
// shortcuts: [
// {
// name: "Demo",
// short_name: "Demo",
// url: "/demo/",
// icons: [
// {
// src: "/assets/icon/guide-maskable.png",
// sizes: "192x192",
// purpose: "maskable",
// type: "image/png",
// },
// ],
// },
// ],
// },
// },
},
});
存放你的文章的目录:src/posts
你的所有文章都将存放在这个目录下

Markdown
每一个 Markdown 文件都会被 VuePress Theme Hope 处理,将文件内容渲染为网页内容。
你可以尝试自己编辑 Markdown 文件来修改模板的内容。如果你已启动开发服务器,那么修改后的结果会被实时同步到开发服务器上。
Markdown 语法
如果你尚不了解 Markdown,请查看 Markdown 教程。
大概十五分钟,你就可以学会如何书写 Markdown,看完之后记得回来!
Markdown 语法扩展
- VuePress 自身对 Markdown 语法进行了一些扩展,关于这些扩展的语法,详见 VuePress → Markdown。
- 主题通过 VuePress 插件额外启用了一些语法扩展,详见 指南 → Markdown。
Frontmatter
Frontmatter 是 VuePress 中很重要的一个概念,它用于承载 Markdown 文件的配置。Markdown 文件可以包含一个 YAML Frontmatter。
YAML
如果你对 YAML 也不熟悉,你可以查看 YAML 教程。
你的Markdown文件必须在前面加上一个Frontmatter
Frontmatter 必须在 Markdown 文件的顶部,并且被包裹在一对三短划线中间。下面是一个基本的示例:
---
lang: zh-CN
title: 页面的标题
description: 页面的描述
---
<!-- 这里是 Markdown 内容 -->
...
你也许注意到案例中 Frontmatter 中的字段和 VuePress 配置文件 十分类似。你可以通过 Frontmatter 来覆盖当前页面的 lang, title, description 等属性。因此,你可以把 Frontmatter 当作页面级作用域的配置,它通常具有最高优先级,所作配置仅对当前页面生效。
