Vitepress 简介
🎉 💯 VitePress 是一个静态站点生成器 (SSG),专为构建快速、以内容为中心的站点而设计。简而言之,VitePress 获取用 Markdown 编写的内容,对其应用主题,并生成可以轻松部署到任何地方的静态 HTML 页面。
官方网站:https://vitejs.cn/vitepress/guide/what-is-vitepress
使用场景
- 文档。 VitePress 附带一个专为技术文档设计的默认主题。Vue.js 官方文档也是基于 VitePress 的。但是为了可以在不同的翻译文档之间切换,它自定义了自己的主题。
- 博客、档案盒营销网站。VitePress 支持完全的自定义主题,具有标准 Vite + Vue 应用程序的开发体验。基于 Vite 构建还意味着可以直接利用其生态系统中丰富的 Vite 插件。此外,VitePress 提供了灵活的 API 来加载数据 (本地或远程),也可以动态生成路由。只要可以在构建时确定数据,就可以使用它来构建几乎任何东西。
开发体验
- Vite 驱动:即时服务器启动,始终反应编辑变化,无需重新加载页面。
- 内置 markdown 扩展:表格、语法高亮...应有尽有,提供了许多用于处理代码的高级功能,使其真正成为技术文档的理想选择。
- Vue 增强的 markdown:每个 markdown 页面都是 Vue 单文件组件,这要归功于 Vue 模板与 HTML 的 100%语法兼容性。可以使用 Vue 模板语法或者导入的 Vue 组件在静态内容中嵌入交互性。
性能
与许多传统的 SSG 不同,每次导航都会导致页面完全重新加载,VitePress 生成的站点在初次访问时提供静态 HTMl,但他变成了单页应用程序进行站点内的后续导航。这种模式为性能提供了最佳平衡。
快速的初始加载 对任何页面的初次访问都将会是静态的、预呈现的 HTML,以实现极快的加载速度和最佳的 SEO。然后页面加载一个 JavaScript bundle,将页面变成 Vue SPA (这被称为“激活”)。与 SPA 激活缓慢的常见假设不同,由于 Vue 3 良好的原始性能和编译优化,这个过程实际上非常快。在 PageSpeed Insights 上,典型的 VitePress 站点即使在网络速度较慢的低端移动设备上也能获得近乎完美的性能分数。
加载完成后可以快速切换:更重要的是,SPA 模型在首次加载后能够提升用户体验。用户在站点内导航时,不会再触发整个页面的刷新。而是通过获取并动态更新页面的内容来实现切换。VitePress 还会自动预加载视口范围内链接对应的页面片段。这样一来,大部分情况下,用户在加载完成后就能立即浏览新页面。
高效的交互:为了能够嵌入静态 Markdown 中的动态 Vue 部分,每个 Markdown 页面都被处理为 Vue 组件并编译成 JavaScript。这听起来可能效率低下,但 Vue 编译器足够聪明,可以将静态和动态部分分开,从而最大限度地减少激活成本和有效负载大小。对于初始的页面加载,静态部分会自动从 JavaScript 有效负载中删除,并在激活期间跳过。
路由配置
基于文件的路由
VitePress 使用基于文件的路由,这意味着生成的 HTML 页面是从源 Markdown 文件的目录结构映射而来的。例如,给定以下目录结构:
.
├─ guide
│ ├─ getting-started.md
│ └─ index.md
├─ index.md
└─ prologue.md
2
3
4
5
6
生成的 HTML 页面:
index.md --> /index.html (可以通过 / 访问)
prologue.md --> /prologue.html
guide/index.md --> /guide/index.html (可以通过 /guide/ 访问)
guide/getting-started.md --> /guide/getting-started.html
2
3
4
生成的 HTML 可以托管在任何支持静态文件的 Web 服务器上。
根目录
当从命令行运行 vitepress dev 或 vitepress build 时,VitePress 将使用当前工作目录作为项目根目录。要将子目录指定为根目录,需要将相对路径传递给命令。例如,如果 VitePress 项目位于 ./docs,应该运行 vitepress dev docs:
.
├─ docs # 项目根目录
│ ├─ .vitepress # 配置目录
│ ├─ getting-started.md
│ └─ index.md
└─ ...
2
3
4
5
6
这将导致以下源代码到 HTML 的映射:
docs/index.md --> /index.html (可以通过 / 访问)
docs/getting-started.md --> /getting-started.html
2
源目录
源目录是 Markdown 源文件相对于项目根目录所在的位置。默认情况下,它与项目根目录相同。但是,可以通过 srcDir 配置选项对其进行配置。例如,对于 srcDir: 'src',文件结构将如下所示:
. # 项目根目录
├─ .vitepress # 配置目录
└─ src # 源目录
├─ getting-started.md
└─ index.md
2
3
4
5
生成的源代码到 HTML 的映射:
src/index.md --> /index.html (可以通过 / 访问)
src/getting-started.md --> /getting-started.html
2
页面链接
在页面之间链接时,可以使用绝对路径和相对路径。请注意,虽然 .md 和 .html 扩展名都可以使用,但最佳做法是省略文件扩展名,以便 VitePress 可以根据配置生成最终的 URL。
# 连接到内部页面 推荐写法:不添加.md .html后缀
[Getting Started](./getting-started)
[Getting Started](../guide/getting-started)
# 连接到外部页面
[Link to pure.html](http://baidu.com){target="_self"}
2
3
4
5
6
动态路由参数
可以使用单个 Markdown 文件和动态数据生成许多页面。例如,可以创建一个 packages/[pkg].md 文件,为项目中的每个包生成相应的页面。这里,[pkg] 段是一个路由参数,用于区分每个页面。
Markdown 路由文件可以通过 $params 全局属性访问 Vue 表达式中的当前页面参数:
- package name: {{ $params.pkg }}
- version: {{ $params.version }}
2
还可以通过 useData 运行时 API 访问当前页面的参数。这在 Markdown 文件和 Vue 组件中都可用:
<script setup>
import { useData } from "vitepress";
// params 是一个 Vue ref
const { params } = useData();
console.log(params.value);
</script>
2
3
4
5
6
7
8
渲染原始内容
传递给页面的参数将在客户端 JavaScript payload 中序列化,因此应该避免在参数中传递大量数据,例如从远程 CMS 获取的原始 Markdown 或 HTML 内容。
相反,可以使用每个路径对象上的 content 属性将此类内容传递到每个页面:
export default {
async paths() {
const posts = await (await fetch("https://my-cms.com/blog-posts")).json();
return posts.map(post => {
return {
params: { id: post.id },
content: post.content, // 原始 Markdown 或 HTML
};
});
},
};
2
3
4
5
6
7
8
9
10
11
12
然后,使用以下特殊语法将内容呈现为 Markdown 文件本身的一部分:
<!-- @content -->
markdown 语法
标题
# 标题一
## 标题二
### 标题三
#### 标题四
##### 标题五
###### 标题六 最多 6 层标题
2
3
4
5
6
7
8
9
10
11
列表
<!-- 无序列表 也可以使用* + 符号 -->
- 列表项 1
- 列表项 2
- 列表项 3
<!-- 有序列表 -->
1. item1
2. item2
3. item3
2
3
4
5
6
7
8
9
10
11
- 列表项 1
- 列表项 2
- 列表项 3
- item1
- item2
- item3
文字效果
*斜体Ctrl + I*
或者_斜体Ctrl + I_
斜体 Ctrl + I**加粗Ctrl + B**
加粗 Ctrl + B***加粗&斜体***
或**_加粗&斜体_**
加粗&斜体~~删除线 ~~
~~删除线 ~~`<style>原样输出`
<style>原样输出
引用
> 区块引用
>
> > 区块嵌套
2
3
区块引用
区块嵌套
分割线
---
也可以用多个*****
或者_____
实现分割线效果:
缩进
段首缩进 空格+回车换行
段首缩进 空格+回车换行
  段首缩进 空格+回车换行
2
3
段首缩进 空格+回车换行
段首缩进 空格+回车换行
段首缩进 空格+回车换行
表格
| 默认左对齐 | 居中对齐 | 右对齐 |
| ------------- | :-----------: | -----: |
| col 3 is | right-aligned | $1600 |
| col 2 is | centered | $12 |
| zebra stripes | are neat | $1 |
2
3
4
5
默认左对齐 | 居中对齐 | 右对齐 |
---|---|---|
col 3 is | right-aligned | $1600 |
col 2 is | centered | $12 |
zebra stripes | are neat | $1 |
Emoji 🎉
🎉 💯 :tada: :100:
🎉 💯 🎉 💯
链接
行内连接:[百度首页](http://baidu.com)
直接连接(必须协议开头):<http://cnblogs.com/> http://cnblogs.com/
参考连接: [Google][1] than from [Yahoo][2] or [MSN][3].
[1]: http://google.com/ "Google Alt"
[2]: http://search.yahoo.com/ "Yahoo Alt"
[3]: http://search.msn.com/ "MSN Alt"
2
3
4
5
6
7
8
9
行内连接:百度首页
直接连接(必须协议开头):http://cnblogs.com/ http://cnblogs.com/
参考连接: Google than from Yahoo or MSN.
图片

![参考形式][id]
[id]: https://gips2.baidu.com/it/u=1651586290,17201034&fm=3028&app=3028&f=JPEG&fmt=auto&q=100&size=f300_400 "Title 信息"
2
3
4
5
视频
<iframe
width="100%"
height="500"
src="../../tools/package/storybook.mp4"
title="markdown video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen>
</iframe>
2
3
4
5
6
7
8
9
数学公式
- 行内公式
$E=mc^2$
$E=mc^2$
- 居中公式块
$$
\sum_{i=0}^n i^2=\frac{(n^2+n)(2n+1)}{6} \tag{1}
$$
2
3
$$ \sum_{i=0}^n i^2=\frac{(n^2+n)(2n+1)}{6} \tag{1} $$
- 上标和下标
$$
x_i^3+y_i^3=z_i^3
$$
2
3
$$ x_i^3+y_i^3=z_i^3 $$
- 括号
$$
\{[(x_1+x_2)^2-(y_1-y_2)^4]\times w\}
\times (z_1^2-z_2^2) \tag{3}
$$
$\lg 10^3$
$\log_2 10$
$\ln (\pi+2)$
$$
\sin(x+y)+\cos(y+z)+\tan(z+x)+\arcsin(x+y+z) \tag{7}
$$
2
3
4
5
6
7
8
9
10
11
12
$$ {[(x_1+x_2)^2-(y_1-y_2)^4]\times w} \times (z_1^2-z_2^2) \tag{3} $$
$\lg 10^3$ $\log_2 10$ $\ln (\pi+2)$
$$ \sin(x+y)+\cos(y+z)+\tan(z+x)+\arcsin(x+y+z) \tag{7} $$
- 累加、累乘、并集和交集
$$
Y_i=\sum_{i=0}^{n} X_i \tag{5}
$$
$$
\sum_{i=1}^n \frac{1}{i^2} \quad and
\quad \prod_{i=1}^n \frac{1}{i^2} \quad
and \quad \bigcup_{i=1}^{2} \Bbb{R}
\quad and \quad \bigcap_{i=1}^3 X_i \tag{6}
$$
2
3
4
5
6
7
8
9
10
$$ Y_i=\sum_{i=0}^{n} X_i \tag{5} $$
$$ \sum_{i=1}^n \frac{1}{i^2} \quad and \quad \prod_{i=1}^n \frac{1}{i^2} \quad and \quad \bigcup_{i=1}^{2} \Bbb{R} \quad and \quad \bigcap_{i=1}^3 X_i \tag{6} $$
自定义容器
自定义容器可以通过它们的类型、标题和内容来定义。
markdown 插件赋予 markdown 的功能
::: info
This is an info box.
:::
::: tip
This is a tip.
:::
::: warning
This is a warning.
:::
::: danger
This is a dangerous warning.
:::
::: details 点我查看代码,这是自定义标题
This is a details block.
:::
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
编译后输出样式为:
信息
This is an info box.
提示
This is a tip.
警告
This is a warning.
危险
This is a dangerous warning.
详细信息
This is a details block.
代码效果
代码块行样式
高亮指定行:
```js{1-2,4} export default { data () { return { msg: `由js{1-2,4}高亮此行!`, motd: '由注释:[!code highlight]高亮此行',// [!code highlight] lorem: '聚焦此行',// [!code focus] q: '显示-号',// [!code --] w: '显示+号',// [!code ++] Error: 'Error背景色', // [!code error] Warning: 'Warning背景色' // [!code warning] } } } ```
export default {
data () {
return {
msg: `由js{1-2,4}高亮此行!`,
motd: '由注释:[!code highlight]高亮此行',
lorem: '聚焦此行',
q: '显示-号',
w: '显示+号',
Error: 'Error背景色',
Warning: 'Warning背景色'
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
启用和禁用行号
```ts:line-numbers=2 // 行号已启用,并从 2 开始 const line3 = 'This is line 3' const line4 = 'This is line 4' ```
// 行号已启用,并从 2 开始
const line3 = 'This is line 3'
const line4 = 'This is line 4'
3
4
导入代码片段
// @为源目录 #snippet代码指定部分 5-10为需要高亮的行
<<< @/home.md{5-10}
2
---
layout: home
title: VitePress 技术文档站点
titleTemplate: 专业的前端技术知识库
hero:
name: 💻 VitePress 技术文档
text: 🚀 现代化前端知识库
tagline: 📚 专注技术分享 | 免费开源维护 | 持续更新迭代
image:
src: /images/hello.svg
alt: VitePress Logo
actions:
- theme: brand
text: 🎯 开始探索
link: /frontEnd/css/dom
- theme: alt
text: 📖 查看简历
link: /
- theme: alt
text: 🔗 GitHub
link: https://github.com/jinxi1334640772
features:
- icon: 🎨
title: 全面的技术栈
details: 涵盖前端、后端、网络工程、开发工具等多个技术领域,从基础到进阶的完整知识体系
- icon: 🚀
title: 现代化技术
details: 基于 Vue 3 + TypeScript + Vite 构建,采用最新的前端技术栈和开发理念
- icon: 📱
title: 响应式设计
details: 完美适配桌面端和移动端,提供一致的阅读体验,随时随地学习技术知识
- icon: 🔍
title: 智能搜索
details: 内置本地搜索功能,支持全文检索,快速定位所需技术内容
- icon: 🎯
title: 实战导向
details: 注重实际应用,提供大量可运行的代码示例和最佳实践案例
- icon: 🌐
title: 持续更新
details: 跟踪最新技术趋势,定期更新内容,确保技术文档的时效性和准确性
- icon: 🛠️
title: 开发工具
details: 详细介绍各种开发工具的使用方法,提升开发效率和代码质量
- icon: 📊
title: 性能优化
details: 深入解析前端性能优化策略,帮助开发者构建高性能的Web应用
- icon: 🔧
title: 工程化实践
details: 分享现代前端工程化的最佳实践,从构建工具到部署流程的完整指南
---
<style>
:root {
--vp-home-hero-name-color: transparent;
--vp-home-hero-name-background: -webkit-linear-gradient(120deg, #bd34fe 30%, #41d1ff);
--vp-home-hero-image-background-image: linear-gradient(-45deg, #bd34fe 50%, #47caff 50%);
--vp-home-hero-image-filter: blur(44px);
}
@media (min-width: 640px) {
:root {
--vp-home-hero-image-filter: blur(56px);
}
}
@media (min-width: 960px) {
:root {
--vp-home-hero-image-filter: blur(68px);
}
}
</style>
## 🌟 技术栈概览
### 前端技术
- **基础技术**: HTML5, CSS3, JavaScript ES6+, TypeScript
- **框架生态**: Vue 2/3, React, Angular, Svelte
- **构建工具**: Webpack, Vite, Rollup, Parcel
- **UI框架**: Element UI/Plus, Ant Design, Tailwind CSS
- **状态管理**: Vuex, Pinia, Redux, MobX
### 后端技术
- **运行时**: Node.js, Deno, Bun
- **框架**: Express, Koa, Nest.js, Fastify
- **数据库**: MongoDB, MySQL, PostgreSQL, Redis
- **服务器**: Nginx, Apache, Docker, Kubernetes
### 开发工具
- **版本控制**: Git, GitHub, GitLab
- **构建部署**: Jenkins, GitHub Actions, Docker
- **代码质量**: ESLint, Prettier, Husky, Lint-staged
- **测试工具**: Jest, Cypress, Vitest, Playwright
### 跨端开发
- **移动端**: uni-app, Taro, React Native, Flutter
- **桌面端**: Electron, Tauri, PWA
- **小程序**: 微信小程序, 支付宝小程序, 抖音小程序
## 📈 内容统计
<div class="stats-container">
<div class="stat-item">
<div class="stat-number">500+</div>
<div class="stat-label">技术文档</div>
</div>
<div class="stat-item">
<div class="stat-number">1000+</div>
<div class="stat-label">代码示例</div>
</div>
<div class="stat-item">
<div class="stat-number">50+</div>
<div class="stat-label">技术栈</div>
</div>
<div class="stat-item">
<div class="stat-number">100+</div>
<div class="stat-label">实用工具</div>
</div>
</div>
<style>
.stats-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 2rem;
margin: 2rem 0;
text-align: center;
}
.stat-item {
padding: 2rem;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 12px;
color: white;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
transition: transform 0.3s ease;
}
.stat-item:hover {
transform: translateY(-5px);
}
.stat-number {
font-size: 3rem;
font-weight: bold;
margin-bottom: 0.5rem;
}
.stat-label {
font-size: 1.2rem;
opacity: 0.9;
}
</style>
## 🎯 学习路线
### 初学者路线
1. **基础知识** → [HTML & CSS](./frontEnd/css/dom.md)
2. **核心语言** → [JavaScript](./frontEnd/javascript/)
3. **框架入门** → [Vue 基础](./frontEnd/web/vue.md)
4. **工程化** → [构建工具](./tools/buildTools/vite.md)
### 进阶路线
1. **深入框架** → [Vue 3 高级特性](./frontEnd/web/vue.md)
2. **性能优化** → [前端性能](./performace/performace.md)
3. **跨端开发** → [uni-app](./spanEnd/uniapp/) / [Taro](./spanEnd/Taro/)
4. **全栈开发** → [Node.js](./afterEnd/node/)
### 专家路线
1. **架构设计** → [系统架构](./tools/questions/system.md)
2. **微前端** → [qiankun 实践](./frontEnd/web/qiankun.md)
3. **团队管理** → [项目管理](./tools/stardard/quality.md)
4. **技术分享** → [知识输出](./tools/study.md)
## 🔥 热门文章
- [🚀 Vue 3 Composition API 完全指南](./frontEnd/web/vue.md)
- [⚡ Vite 构建工具深度解析](./tools/buildTools/vite.md)
- [🎯 前端性能优化最佳实践](./performace/performace.md)
- [🔧 现代前端工程化配置](./tools/buildTools/webpack.md)
- [📱 uni-app 跨端开发实战](./spanEnd/uniapp/)
- [🌐 HTTP 协议深度解析](./network/http/)
- [🛠️ 常用工具库推荐](./tools/package/lodash.md)
- [❓ 前端面试题汇总](./tools/questions/handwrite.md)
## 🤝 参与贡献
欢迎大家参与到这个技术文档项目中来!您可以:
- 🐛 报告问题和Bug
- 📝 提交内容更新和修正
- 💡 提供新的技术文档
- 🌟 给项目一个Star支持
## 📞 联系方式
- 📧 **邮箱**: 1334640772@qq.com
- 🐱 **GitHub**: [@jinxi1334640772](https://github.com/jinxi1334640772)
- 💎 **掘金**: [掘金主页](https://juejin.cn/user/1451011080204040)
- 🌐 **个人网站**: [https://jinxi1334640772.github.io](https://jinxi1334640772.github.io)
---
::: tip 💡 小贴士
这个网站是完全开源的,所有内容都可以在 [GitHub](https://github.com/jinxi1334640772/jinxi1334640772.github.io) 上找到。如果你觉得内容有帮助,欢迎给项目一个 ⭐ Star!
:::
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
包含 markdown 文件
以下为导入的 markdown 文件输出的结果:
title: VitePress 技术文档站点
titleTemplate: 专业的前端技术知识库
hero:
name: 💻 VitePress 技术文档
text: 🚀 现代化前端知识库
tagline: 📚 专注技术分享 | 免费开源维护 | 持续更新迭代
image:
4
5
6
7
8
9
10
代码组
/**
* @type {import('vitepress').UserConfig}
*/
const config = {
// ...
};
export default config;
2
3
4
5
6
7
8
import type { UserConfig } from "vitepress";
const config: UserConfig = {
// ...
};
export default config;
2
3
4
5
6
7
在 Markdown 使用 Vue
提示
VitePress 带有内置的 Markdown 扩展。这里为提示 tip。获取页首定义的 custom 变量 :自定义变量:在{{ $frontmatter.custom }}中引用任何变量
在 VitePress 中,每个 Markdown 文件都被编译成 HTML,而且将其作为 Vue 单文件组件处理。这意味着可以在 Markdown 中使用任何 Vue 功能,包括动态模板、使用 Vue 组件或通过添加 <script>
标签为页面的 Vue 组件添加逻辑。
值得注意的是,VitePress 利用 Vue 的编译器自动检测和优化 Markdown 内容的纯静态部分。在客户端激活期间也会跳过它们。
在 Markdown 中使用
<style scoped>
需要为当前页面的每个元素添加特殊属性,这将显著增加页面的大小。当我们需要局部范围的样式时<style module>
是首选。
<script setup>
// 可以引入外部数据
import { data } from '/example.data.js'
//可以访问 VitePress 的运行时 API,例如 useData 辅助函数,它提供了当前页面的元数据:
import { useData } from 'vitepress'
import { ref } from 'vue'
const { page } = useData()
const count = ref(1000)
</script>
<pre>导入定义的数据:{{ data }}</pre>
<pre>useData()获取的page数据:{{ page }}</pre>
<pre :class="$style.button" >ref(1000)数据: {{ count }}</pre>
<button :class="$style.button" @click="count++">点击:count++</button>
<!-- 使用CSS module -->
<style module>
.button {
color: red;
font-weight: bold;
}
</style>
<!-- 使用CSS预处理器 -->
<style lang="scss">
.title {
font-size: 20px
}
</style>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
导入定义的数据:{ "hello": "world" }
useData()获取的page数据:{ "title": "配置页面显示:页面title", "description": "", "frontmatter": { "title": "配置页面显示:页面title", "editLink": true, "custom": "自定义变量:在{{ $frontmatter.custom }}中引用任何变量" }, "headers": [], "relativePath": "frontEnd/web/VitePress.md", "filePath": "frontEnd/web/VitePress.md", "lastUpdated": 1734399712000 }
ref(1000)数据: 1000
如果一个组件要在大多数页面上使用,可以通过自定义 Vue 实例来全局注册它们。
确保自定义组件的名称包含连字符或采用 PascalCase。否则,它将被视为内联元素并包裹在
<p>
标签内,这将导致激活不匹配,因为<p>
不允许将块元素放置在其中。
VitePress 内置支持 CSS 预处理器:.scss、.sass、.less、.styl 和 . stylus 文件。无需为它们安装 Vite 专用插件,但必须安装相应的预处理器
使用 teleport 传递组件内容
VitePress 目前只有使用 teleport 传送到 body 的 SSG 支持。对于其他地方,可以将它们包裹在内置的 <ClientOnly>
组件中,或者通过 postRender 钩子将 teleport 标签注入到最终页面 HTML 中的正确位置。
<ClientOnly>
<Teleport to="#modal">
<div></div>
</Teleport>
</ClientOnly>
2
3
4
5