docs: add `zh-CN` transition

pull/2249/head
vanch 3 years ago
parent e91e0f91b2
commit 1b0424ffb6

@ -7,7 +7,7 @@ const pkg = require('vitepress/package.json')
export default defineConfig({
lang: 'en-US',
title: 'VitePress',
description: 'Vite & Vue powered static site generator.',
// description: 'Vite & Vue powered static site generator.',
lastUpdated: true,
cleanUrls: true,
@ -24,14 +24,40 @@ export default defineConfig({
}
]
],
locales: {
root: {
label: 'English',
lang: 'en',
description: 'Vite & Vue powered static site generator.',
themeConfig: {
nav: nav(),
sidebar: {
'/guide/': sidebarGuide(),
'/reference/': sidebarReference()
}
}
},
zh: {
label: '简体中文',
lang: 'zh-CN',
link: '/zh/',
description: 'Vite & Vue powered static site generator.',
themeConfig: {
nav: zhNav(),
sidebar: {
'/zh/guide/': zhSidebarGuide(),
'/zh/reference/': zhSidebarReference()
}
}
}
},
themeConfig: {
nav: nav(),
// nav: nav(),
sidebar: {
'/guide/': sidebarGuide(),
'/reference/': sidebarReference()
},
// sidebar: {
// '/guide/': sidebarGuide(),
// '/reference/': sidebarReference()
// },
editLink: {
pattern: 'https://github.com/vuejs/vitepress/edit/main/docs/:path',
@ -225,3 +251,125 @@ function sidebarReference() {
}
]
}
function zhNav() {
return [
{
text: '指引',
link: '/zh/guide/what-is-vitepress',
activeMatch: '/zh/guide/'
},
{
text: '配置参考',
link: '/zh/reference/site-config',
activeMatch: '/zh/reference/'
},
{
text: pkg.version,
items: [
// { text: 'itemA', link: '/item-1' },
{
text: '更新日志',
link: 'https://github.com/vuejs/vitepress/blob/main/CHANGELOG.md'
},
{
text: '贡献',
link: 'https://github.com/vuejs/vitepress/blob/main/.github/contributing.md'
}
]
}
]
}
function zhSidebarGuide() {
return [
{
text: '介绍',
collapsed: true,
items: [
{ text: '什么是 VitePress?', link: '/zh/guide/what-is-vitepress' },
{ text: '快速开始', link: '/zh/guide/getting-started' },
{ text: '路由', link: '/zh/guide/routing' },
{ text: '部署', link: '/zh/guide/deploy' }
]
},
{
text: '编写',
collapsed: true,
items: [
{ text: 'Markdown 基础语法', link: '/zh/guide/markdown-base' },
{ text: 'Markdown 扩展', link: '/zh/guide/markdown' },
{ text: '静态资源处理', link: '/zh/guide/asset-handling' },
{ text: 'Frontmatter', link: '/zh/guide/frontmatter' },
{ text: '在 Markdown 中 使用 Vue', link: '/zh/guide/using-vue' },
{ text: '国际化', link: '/zh/guide/i18n' }
]
},
{
text: '自定义',
collapsed: true,
items: [
{ text: '使用自定义主题', link: '/guide/custom-theme' },
{ text: '扩展默认主题', link: '/guide/extending-default-theme' },
{ text: '构建时数据加载', link: '/guide/data-loading' },
{ text: 'SSR 兼容性', link: '/guide/ssr-compat' },
{ text: '连接到 CMS', link: '/guide/cms' }
]
},
{
text: '实验性的',
collapsed: true,
items: [
{
text: 'MPA Mode',
link: '/guide/mpa-mode'
}
]
},
{
text: '配置 & API 参考',
link: '/reference/site-config'
}
]
}
function zhSidebarReference() {
return [
{
text: '参考',
items: [
{ text: '站点配置', link: '/zh/reference/site-config' },
{ text: 'Frontmatter 配置', link: '/zh/reference/frontmatter-config' },
{ text: 'Runtime API', link: '/zh/reference/runtime-api' },
{ text: 'CLI', link: '/zh/reference/cli' },
{
text: '默认主题',
items: [
{ text: '概览', link: '/zh/reference/default-theme-config' },
{ text: '导航栏', link: '/zh/reference/default-theme-nav' },
{ text: '侧边栏', link: '/zh/reference/default-theme-sidebar' },
{ text: '主页', link: '/zh/reference/default-theme-home-page' },
{ text: '页脚', link: '/zh/reference/default-theme-footer' },
{ text: '布局', link: '/zh/reference/default-theme-layout' },
{ text: '徽标', link: '/zh/reference/default-theme-badge' },
{ text: '团队', link: '/zh/reference/default-theme-team-page' },
{
text: '上(下)一篇',
link: '/zh/reference/default-theme-prev-next-links'
},
{ text: '编辑链接', link: '/zh/reference/default-theme-edit-link' },
{
text: '最近更新时间',
link: '/zh/reference/default-theme-last-updated'
},
{ text: '搜索', link: '/zh/reference/default-theme-search' },
{
text: 'Carbon Ads',
link: '/zh/reference/default-theme-carbon-ads'
}
]
}
]
}
]
}

@ -0,0 +1,64 @@
# 资源处理 {#asset-handling}
## 引用静态资源 {#referencing-static-assets}
所有的 Markdown 文件都会被编译成 Vue 组件,并由 [Vite](https://vitejs.dev/guide/assets.html) 处理。你可以,**并且应该**使用相对路径来引用任何资源:
```md
![An image](./image.png)
```
你可以在 Markdown 文件、主题中的 `*.vue` 组件、样式和普通的 `.css` 文件中引用静态资源,通过使用绝对路径 (基于项目根目录) 或者相对路径 (基于文件系统)。后者类似于 ViteVue CLI或者 webpack 的 `file-loader`的行为。
常见的图像,媒体和字体文件会被自动检测并包含为资源。
所有引用的资源,包括那些使用绝对路径的,都会在生产构建过程中被复制到输出目录,并具有哈希文件名。从未使用过的资源将不会被复制。小于 4kb 的图像资源将会被使用 base64 内联 - 这可以通过 [`vite`](../reference/site-config#vite) 配置选项进行配置。
所有**静态**路径引用,包括绝对路径,都应基于你的工作目录结构。
## public 目录 {#the-public-directory}
有时你可能需要提供一些静态资源,但这些资源没有直接被 Markdown 或主题组件直接引用,或者你可能想以原始文件名提供提供某些文件。此类文件的例子包括 `robot.txt`favicons 和 PWA 图标。
你可以将这些文件放置在[源目录](./routing#source-directory)的 `public` 目录中。例如,如果你的项目根目录是 `./docs`,并且使用默认源目录位置,那么你的 public 目录将是 `./docs/public`
放置在 `public` 中的资源将按原样复制到输出目录的根目录中。
请注意,你应使用根绝对路径来引用放置在 `public` 中的文件 - 例如,`public/icon.png` 应始终在源代码中作为 `/icon.png` 引用。
但有一个例外:如果你在 `public` 中有一个 HTML 页面,并从主站点链接到它,路由默认会产生 404 错误。为了解决这个问题VitePress 提供了 `pathname//` 协议,它允许你像链接外部页面一样链接到同一域名的另一个页面。比较这两个链接:
- [/pure.html](/pure.html)
- <pathname:///pure.html>
## 根 URL {#base-url}
如果你的网站部署在非根 URL 上,则需要在 `.vitepress/config.js` 中设置 `base` 选项。例如,如果你计划将网站部署到 `https://foo.github.io/bar/`,则 `base` 应设置为 `'/bar/'`(它应始终以斜杠开头和结尾)。
所有静态资源路径都会被自动处理,来适应不同的 `base` 配置值。例如,如果你的 markdown 中有一个对 `public` 中的资源的绝对引用:
```md
![An image](/image-inside-public.png)
```
在这种情况下,更改 `base` 配置值时,你**无需**更新该引用。
但是如果你正在编写一个主题组件,它动态的链接到资源,例如一个图片,它的 `src` 基于主题配置值:
```vue
<img :src="theme.logoPath" />
```
在这种情况下,建议使用 VitePress 提供的 [`withBase` helper](../reference/runtime-api#withbase) 来包装路径:
```vue
<script setup>
import { withBase, useData } from 'vitepress'
const { theme } = useData()
</script>
<template>
<img :src="withBase(theme.logoPath)" />
</template>
```

@ -0,0 +1,56 @@
---
outline: deep
---
# 连接到 CMS {#connecting-to-a-cms}
## 一般的工作流 {#general-workflow}
将 VitePress 连接到 CMS 主要围绕 [动态路由](./routing#dynamic-routes) 而展开。在继续之前,请确保了解它的工作原理。
由于每个 CMS 的工作方式都不同,因此我们只能提供一个通用的工作流程,你需要根据具体情况进行调整。
1. 如果你的 CMS 需要身份验证,请创建一个 `.env` 文件来存储你的 API 令牌并加载它:
```js
// posts/[id].paths.js
import { loadEnv } from 'vitepress'
const env = loadEnv('', process.cwd())
```
2. 从 CMS 获取必要的数据并将其格式调整为合适的路径数据:
```js
export default {
async paths() {
// 使用相应的 CMS 客户端库 (如果需要的话)
const data = await (await fetch('https://my-cms-api', {
headers: {
// 如果需要token 的话请在这里填写
}
})).json()
return data.map(entry => {
return {
params: { id: entry.id, /* title, authors, date etc. */ },
content: entry.content
}
})
}
}
```
3. 在页面中渲染内容:
```md
# {{ $params.title }}
- by {{ $params.author }} on {{ $params.date }}
<!-- @content -->
```
## 整合指南 {#integration-guides}
如果你已经写了一篇关于如何将 VitePress 与特定 CMS 集成的指南,请点击下面的“在 GitHub 上编辑此页面”链接将它提交到这里!

@ -0,0 +1,222 @@
# 自定义主题 {#using-a-custom-theme}
## 主题解析 {#theme-resolving}
你可以通过创建一个 `.vitepress/theme/index.js``.vitepress/theme/index.ts` 文件 (即“主题入口文件”) 来启用自定义主题:
```
.
├─ docs # project root
│ ├─ .vitepress
│ │ ├─ theme
│ │ │ └─ index.js # theme entry
│ │ └─ config.js # config file
│ └─ index.md
└─ package.json
```
当检测到存在主题入口文件时VitePress 总会使用自定义主题而不是默认主题。但你可以[扩展默认主题](./extending-default-theme)来在其基础上实现更高级的自定义主题。
## 主题接口 {#theme-interface}
VitePress 自定义主题被定义为一个对象,该对象具有如下接口:
```ts
interface Theme {
/**
* Root layout component for every page
* @required
*/
Layout: Component
/**
* Enhance Vue app instance
* @optional
*/
enhanceApp?: (ctx: EnhanceAppContext) => Awaitable<void>
/**
* Extend another theme, calling its `enhanceApp` before ours
* @optional
*/
extends?: Theme
}
interface EnhanceAppContext {
app: App // Vue app instance
router: Router // VitePress router instance
siteData: Ref<SiteData> // Site-level metadata
}
```
主题入口文件需要将主题作为默认导出来导出:
```js
// .vitepress/theme/index.js
// You can directly import Vue files in the theme entry
// VitePress is pre-configured with @vitejs/plugin-vue.
import Layout from './Layout.vue'
export default {
Layout,
enhanceApp({ app, router, siteData }) {
// ...
}
}
```
默认导出是自定义主题的唯一方式,并且只有 `Layout` 属性是必须的。所以从技术上讲,一个 VitePress 主题可以只是一个单独的 Vue 组件。
在你的组件内部,它的工作方式就像是一个普通的 Vite + Vue 3 应用。请注意,主题还需要保证 [SSR 兼容](./ssr-compat)。
## 构建布局 {#building-a-layout}
最基本的布局组件需要包含一个 [`<Content />`](../reference/runtime-api#content) 组件:
```vue
<!-- .vitepress/theme/Layout.vue -->
<template>
<h1>Custom Layout!</h1>
<!-- this is where markdown content will be rendered -->
<Content />
</template>
```
上面的布局只是将每个页面的 markdown 渲染为 HTML。我们添加的第一个改进是处理 404 错误:
```vue{1-4,9-12}
<script setup>
import { useData } from 'vitepress'
const { page } = useData()
</script>
<template>
<h1>Custom Layout!</h1>
<div v-if="page.isNotFound">
Custom 404 page!
</div>
<Content v-else />
</template>
```
[`useData()`](../reference/runtime-api#usedata) 为我们提供了所有的运行时数据,以便我们根据不同条件渲染不同的布局。我们可以访问的另一个数据是当前页面的 frontmatter。通过利用这个数据我们允许最终用户控制每个页面的布局。例如用户可以指示一个页面是否使用特殊的主页布局
```md
---
layout: home
---
```
并且我们可以该信息调整我们的主题
```vue{3,12-14}
<script setup>
import { useData } from 'vitepress'
const { page, frontmatter } = useData()
</script>
<template>
<h1>Custom Layout!</h1>
<div v-if="page.isNotFound">
Custom 404 page!
</div>
<div v-if="frontmatter.layout === 'home'">
Custom home page!
</div>
<Content v-else />
</template>
```
当然你可以将布局切分为不同的组件:
```vue{3-5,12-15}
<script setup>
import { useData } from 'vitepress'
import NotFound from './NotFound.vue'
import Home from './Home.vue'
import Page from './Page.vue'
const { page, frontmatter } = useData()
</script>
<template>
<h1>Custom Layout!</h1>
<NotFound v-if="page.isNotFound" />
<Home v-if="frontmatter.layout === 'home'" />
<Page v-else /> <!-- <Page /> renders <Content /> -->
</template>
```
请查看[运行时 API 参考](../reference/runtime-api)获取主题组件中所有可用内容。此外,你可以利用[构建时数据加载](./data-loading) 来生成数据驱动布局 - 例如,一个列出当前项目中所有博客文章的页面。
## 分发自定义主题 {#distributing-a-custom-theme}
分发自定义主题最简单的方式是通过将其作为 [GitHub 模版仓库](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-template-repository) 来提供。
如果你希望将主题作为 npm 包来分发,请按照下面的步骤操作:
1. 在包入口将主题对象作为默认导出来导出。
2. 如果合适的话,将你的主题配置类型定义作为 `ThemeConfig` 导出。
3. 如果你的主题需要调整 VitePress 配置,请在包子路径下 (例如 `my-theme/config`) 下导出该配置,以便用户拓展。
4. 记录主题配置选项 (通过配置文件和 frontmatter)。
5. 提供清晰的说明关于如何使用你的主题 (见下文)。
## 使用自定义主题 {#consuming-a-custom-theme}
要使用外部主题,请从自定义主题入口导入导入它并重新导出:
```js
// .vitepress/theme/index.js
import Theme from 'awesome-vitepress-theme'
export default Theme
```
如果主题需要被拓展:
```js
// .vitepress/theme/index.js
import Theme from 'awesome-vitepress-theme'
export default {
extends: Theme,
enhanceApp(ctx) {
// ...
}
}
```
如果主题需要特殊的 VitePress 配置,你也需要在配置中拓展:
```ts
// .vitepress/theme/config.ts
import baseConfig from 'awesome-vitepress-theme/config'
export default {
// extend theme base config (if needed)
extends: baseConfig
}
```
最后,如果主题为其主题配置提供了类型:
```ts
// .vitepress/theme/config.ts
import baseConfig from 'awesome-vitepress-theme/config'
import { defineConfigWithTheme } from 'vitepress'
import type { ThemeConfig } from 'awesome-vitepress-theme'
export default defineConfigWithTheme<ThemeConfig>({
extends: baseConfig,
themeConfig: {
// Type is `ThemeConfig`
}
})
```

@ -0,0 +1,209 @@
# 构建时数据加载 {#build-time-data-loading}
VitePress 提供了一个叫做**数据加载器**的功能,它允许你加载任意数据并从页面或组件中导入它。数据加载**只在构建时**执行:最终的数据将被序列化为 JavaScript 包中的 JSON。
数据加载器可以被用于获取远程数据,也可以基于本地文件生成元数据。例如,你可以使用数据加载器来解析所有本地 API 页面并自动生成所有 API 入口的索引。
## 基本用法 {#basic-usage}
一个数据加载器文件必须以 `.data.js``.data.ts` 结尾。该文件应该提供一个默认导出的对象,该对象具有 `load()` 方法:
```js
// example.data.js
export default {
load() {
return {
data: 'hello',
}
},
}
```
数据加载器模块只在 Node.js 中执行,因此你可以按需导入 Node API 和 npm 依赖。
然后,你可以在 `.md` 页面和 `.vue` 组件中使用 `data` 命名导出从该文件中导入数据:
```html
<script setup>
import { data } from './example.data.js'
</script>
<pre>{{ data }}</pre>
```
输出:
```json
{
"data": "hello"
}
```
你会注意到数据加载器本身并没有导出 `data`。这是因为 VitePress 在后台调用了 `load()` 方法,并通过名为 `data` 的命名导出隐式地暴露了结果。
即使 loader 是异步的,这也是有效的:
```js
export default {
async load() {
// fetch remote data
return (await fetch('...')).json()
},
}
```
## 使用本地文件生成数据 {#data-from-local-files}
当你需要基于本地文件生成数据时,你应该在数据加载器中使用 `watch` 选项,以便这些文件改动时可以触发热更新。
`watch` 选项也很方便,因为你可以使用 [glob 模式](https://github.com/mrmlnc/fast-glob#pattern-syntax) 匹配多个文件。模式可以相对于加载器文件本身,`load()` 函数将接收匹配文件的绝对路径。
下面的例子展示了如何使用 [csv-parse](https://github.com/adaltas/node-csv/tree/master/packages/csv-parse/) 加载 CSV 文件并将其转换为 JSON。因为此文件仅在构建时执行因此不会将 CSV 解析器发送到客户端!
```js
import fs from 'node:fs'
import { parse } from 'csv-parse/sync'
export default {
watch: ['./data/*.csv'],
load(watchedFiles) {
// watchedFiles will be an array of absolute paths of the matched files.
// generate an array of blog post metadata that can be used to render
// a list in the theme layout
return watchedFiles.map((file) => {
return parse(fs.readFileSync(file, 'utf-8'), {
columns: true,
skip_empty_lines: true,
})
})
},
}
```
## `createContentLoader`
当构建一个内容为主的网站时,我们经常需要创建一个“档案”或“索引”页面:一个我们可以列出内容中的所有可用条目的页面,例如博客文章或 API 页面。我们**可以**直接使用数据加载器 API 实现这一点但由于这是一个常见的用例VitePress 还提供了一个 `createContentLoader` 辅助函数来简化这个过程:
```js
// posts.data.js
import { createContentLoader } from 'vitepress'
export default createContentLoader('posts/*.md' /* options */)
```
该辅助函数接受一个相对于 [项目根目录](./routing#project-root) 的 glob 模式,并返回一个 `{ watch, load }` 数据加载器对象,该对象可以用作数据加载器文件中的默认导出。它还基于文件修改时间戳实现了缓存以提高开发性能。
请注意,加载器仅适用于 Markdown 文件 - 匹配的非 Markdown 文件将被跳过。
加载的数据将是一个类型为 `ContentData[]` 数组:
```ts
interface ContentData {
// mapped absolute URL for the page. e.g. /posts/hello.html
url: string
// frontmatter data of the page
frontmatter: Record<string, any>
// the following are only present if relevant options are enabled
// we will discuss them below
src: string | undefined
html: string | undefined
excerpt: string | undefined
}
```
默认情况下只提供 `url``frontmatter`。这是因为加载的数据将作为 JSON 内联在客户端包中,我们需要谨慎考虑其大小。下面的例子展示了如何使用数据构建最小博客索引页面:
```vue
<script setup>
import { data as posts } from './posts.data.js'
</script>
<template>
<h1>All Blog Posts</h1>
<ul>
<li v-for="post of posts">
<a :href="post.url">{{ post.frontmatter.title }}</a>
<span>by {{ post.frontmatter.author }}</span>
</li>
</ul>
</template>
```
### Options {#options}
默认数据可能不适合所有需求 - 你可以选择使用选项转换数据:
```js
// posts.data.js
import { createContentLoader } from 'vitepress'
export default createContentLoader('posts/*.md', {
includeSrc: true, // include raw markdown source?
render: true, // include rendered full page HTML?
excerpt: true, // include excerpt?
transform(rawData) {
// map, sort, or filter the raw data as you wish.
// the final result is what will be shipped to the client.
return rawData
.sort((a, b) => {
return +new Date(b.frontmatter.date) - +new Date(a.frontmatter.date)
})
.map((page) => {
page.src // raw markdown source
page.html // rendered full page HTML
page.excerpt // rendered excerpt HTML (content above first `---`)
return {
/* ... */
}
})
},
})
```
查看它在 [Vue.js 博客](https://github.com/vuejs/blog/blob/main/.vitepress/theme/posts.data.ts) 中是如何使用的。
`createContentLoader` API 也可以在 [构建钩子](/reference/site-config#build-hooks) 中使用:
```js
// .vitepress/config.js
export default {
async buildEnd() {
const posts = await createContentLoader('posts/*.md').load()
// generate files based on posts metadata, e.g. RSS feed
},
}
```
## 为数据加载器导出类型 {#typed-data-loaders}
当使用 TypeScript 时,你可以像这样为加载器和 `data` 导出类型:
```ts
import { defineLoader } from 'vitepress'
export interface Data {
// data type
}
declare const data: Data
export { data }
export default defineLoader({
// type checked loader options
glob: ['...'],
async load(): Promise<Data> {
// ...
},
})
```
## 配置 {#configuration}
要获取加载器中的配置信息,可以使用如下代码:
```ts
import type { SiteConfig } from 'vitepress'
const config: SiteConfig = (globalThis as any).VITEPRESS_CONFIG
```

@ -0,0 +1,280 @@
---
outline: deep
---
# 部署你的 VitePress 网站 {#deploy-your-vitepress-site}
以下指南基于一些共设前提:
- VitePress 站点位于项目的 `docs` 目录中。
- 你使用的是默认的生成输出目录 `.vitepress/dist`)。
- VitePress 作为本地依赖项安装在项目中,并且你已在 `package.json` 中设置以下脚本:
```json
{
"scripts": {
"docs:build": "vitepress build docs",
"docs:preview": "vitepress preview docs"
}
}
```
## 本地构建与测试 {#build-and-test-locally}
- 你可以运行以下命令来构建文档:
```sh
yarn docs:build
```
- 构建文档后,通过运行以下命令在本地预览它:
```sh
yarn docs:preview
```
`preview` 命令将启动一个本地静态 Web 服务器`http://localhost:4173`,该服务器以 `.vitepress/dist` 作为源文件。这是检查生产版本在本地环境中是否正常的一种简单方法。
- 你可以通过传递`--port`作为参数来配置服务器的端口。
```json
{
"scripts": {
"docs:preview": "vitepress preview docs --port 8080"
}
}
```
现在`docs:preview`方法将在`http://localhost:8080`启动服务器。
## 设定 public 根目录 {#setting-a-public-base-path}
默认情况下,我们假设站点将部署在域名 `/` 的根路径上。如果你的网站将在子路径中提供服务,例如 `https://mywebsite.com/blog/`,则需要在 VitePress 配置中将 [`base`](../reference/site-config#base)选项设置为 `'/blog/'`
**例:**如果你使用的是 Github或 GitLab页面并部署到 `user.github.io/repo/`,请将你的 `base` 设置为 `/repo/`
## HTTP 缓存标头 {#http-cache-headers}
如果可以控制生产服务器上的 HTTP 标头,则可以配置 `cache-control` 标头以在重复访问时获得更好的性能。
生产版本对静态资源JavaScript、CSS 和其他非 `public` 目录中的导入资源)使用哈希文件名。如果你使用浏览器开发工具的网络选项卡检查生产预览,你将看到类似 `app.4f283b18.js` 的文件。
此哈希 `4f283b18` 是从此文件的内容生成的。相同的哈希 URL 保证提供相同的文件内容 —— 如果内容更改URL 也会更改。这意味着你可以安全地为这些文件使用最强的缓存标头。所有此类文件都将放置在输出目录的 `assets/` 中,因此你可以为它们配置以下标头:
```
Cache-Control: max-age=31536000,immutable
```
:::details Netlify 示例 `_headers` 文件
```
/assets/*
cache-control: max-age=31536000
cache-control: immutable
```
注意:该 `_headers` 文件应放置在[public 目录](/guide/asset-handling#the-public-directory)中(在我们的例子中是 `docs/public/_headers`),以便将其逐字复制到输出目录。
[Netlify 自定义标头文档](https://docs.netlify.com/routing/headers/)
:::
:::details Vercel 配置示例 `vercel.json`
```json
{
"headers": [
{
"source": "/assets/(.*)",
"headers": [
{
"key": "Cache-Control",
"value": "max-age=31536000, immutable"
}
]
}
]
}
```
注意:`vercel.json` 文件应放在存储库的根目录中。
[Vercel 关于标头配置的文档](https://vercel.com/docs/concepts/projects/project-configuration#headers)
:::
## 各平台部署指南 {#platform-guides}
### Netlify / Vercel / Cloudflare Pages / AWS Amplify / Render
使用仪表板创建新项目并更改这些设置:
- **构建命令:** `npm run docs:build`
- **输出目录:** `docs/.vitepress/dist`
- **node 版本:** `16` (或更高版本,默认情况下通常为 14 或 16但在 Cloudflare 页面上,默认值仍然是 12因此你可能需要[更改该版本](https://developers.cloudflare.com/pages/platform/build-configuration/))
::: warning 警告
不要为 HTML 代码启用 _Auto Minify_ 等选项。它将从输出中删除对 Vue 有意义的注释。如果被删除,你可能会看到 hydration mismatch 错误。
:::
### GitHub Pages
1. 在你的 theme 配置文件中, `docs/.vitepress/config.js`, 设置 `base` 为 GitHub 仓库的名称。如果你打算把站点部署到 `https://foo.github.io/bar/`,那你就需要把 `base` 设置为 `'/bar/'`。它始终以 `/` 开头结尾。
2. 在项目目录 `.github/workflows` 下创建一个名为 `deploy.yml` 的文件,包含以下内容:
```yaml
name: Deploy
on:
workflow_dispatch: {}
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: actions/setup-node@v3
with:
node-version: 16
cache: npm
- run: npm ci
- name: Build
run: npm run docs:build
- uses: actions/configure-pages@v2
- uses: actions/upload-pages-artifact@v1
with:
path: docs/.vitepress/dist
- name: Deploy
id: deployment
uses: actions/deploy-pages@v1
```
::: tip 提示
请替换相应的分支名称。比如你要建的分支是 `master` ,那么你要把上面文件中的 `main` 换成 `master`
:::
3. 在仓库设置中找到 `Pages` 选项,在 `Build and deployment` 下的 `Source` 中选择 `GitHub Actions`
4. 现在提交你的代码并将其推送到 `main` 分支。
5. 等待 Actions 完成。
6. 在仓库设置中找到 `Pages` 选项,点击 `Visit site` 就可以看到你的网站。现在,你的文档将在你每次推送时自动部署。
### GitLab Pages
1. 将 `docs/.vitepress/config.js` 中的 `outDir` 设置为 `../public`
2. 在 `docs/.vitepress/config.js` 配置文件中,将 `base` 属性设置为 GitLab 存储库的名称。如果计划将站点部署到 `https://foo.gitlab.io/bar/`,则应将 `base` 设置为 `'/bar/'`。它应始终以 `/`开头和结尾。
3. 使用以下内容在项目的根目录中创建一个名为 `.gitlab-ci.yml` 的文件。每当你更改内容时,会自动构建和部署你的站点:
```yaml
image: node:16
pages:
cache:
paths:
- node_modules/
script:
- npm install
- npm run docs:build
artifacts:
paths:
- public
only:
- main
```
4. 或者,如果要使用 _alpine_ 版本的 node则必须手动安装 `git`。在这种情况下,上面的代码修改为:
```yaml
image: node:16-alpine
pages:
cache:
paths:
- node_modules/
before_script:
- apk add git
script:
- npm install
- npm run docs:build
artifacts:
paths:
- public
only:
- main
```
### Azure Static Web Apps {#azure-static-web-apps}
1. 遵循[官方文档](https://docs.microsoft.com/en-us/azure/static-web-apps/build-configuration)。
2. 在配置文件中设置这些值(并删除不需要的值,如 `api_location`
- **`app_location`**: `/`
- **`output_location`**: `docs/.vitepress/dist`
- **`app_build_command`**: `npm run docs:build`
### Firebase {#firebase}
1. 在项目的根目录下创建 `firebase.json``.firebaserc`
`firebase.json`:
```json
{
"hosting": {
"public": "docs/.vitepress/dist",
"ignore": []
}
}
```
`.firebaserc`:
```json
{
"projects": {
"default": "<YOUR_FIREBASE_ID>"
}
}
```
2. 运行 `yarn docs:build` 后,运行此命令进行部署:
```sh
firebase deploy
```
### Surge
1. 运行 `yarn docs:build` 后,运行此命令进行部署:
```sh
npx surge docs/.vitepress/dist
```
### Heroku
1. 遵循 [`heroku-buildpack-static`](https://elements.heroku.com/buildpacks/heroku/heroku-buildpack-static) 中给出的文档和指南。
2. 使用以下内容在项目的根目录中创建一个名为 `static.json` 的文件:
```json
{
"root": "docs/.vitepress/dist"
}
```
### Edgio
请参阅[创建并部署 VitePress 应用程序到 Edgio](https://docs.edg.io/guides/vitepress)。

@ -0,0 +1,217 @@
# 扩展默认主题 {#extending-the-default-theme}
VitePress 默认的主题已经针对文档进行了优化,并且可以进行定制。请参考 [默认主题配置概览](../reference/default-theme-config) 获取完整的选项列表。
但是有一些情况仅靠配置是不够的。例如:
1. 你需要调整 CSS 样式;
2. 你需要修改 Vue 应用实例,例如注册全局组件;
3. 你需要通过 layout 插槽将自定义内容注入到主题中;
这些高级自定义配置将需要使用自定义主题来“拓展”默认主题。
:::tip
在继续之前,请确保首先阅读[自定义主题](./custom-theme)以了解其工作原理。
:::
## 自定义 CSS {#customizing-css}
可以通过覆盖根级别的 CSS 变量来自定义默认主题的 CSS
```js
// .vitepress/theme/index.js
import DefaultTheme from 'vitepress/theme'
import './custom.css'
export default DefaultTheme
```
```css
/* .vitepress/theme/custom.css */
:root {
--vp-c-brand: #646cff;
--vp-c-brand-light: #747bff;
}
```
查看[默认主题 CSS 变量](https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css)来获取可以被覆盖的变量。
## 使用自定义字体 {#using-different-fonts}
VitePress 使用 [Inter](https://rsms.me/inter/) 作为默认字体,并且将其包含在生成的输出中。该字体在生产环境中也会自动预加载。但是如果你要使用不同的主字体,这可能不是一个好的选择。
为了避免在生成后的输出中包含 Inter 字体,请从 `vitepress/theme-without-fonts` 中导入主题:
```js
// .vitepress/theme/index.js
import DefaultTheme from 'vitepress/theme-without-fonts'
import './my-fonts.css'
export default DefaultTheme
```
```css
/* .vitepress/theme/custom.css */
:root {
--vp-font-family-base: /* normal text font */
--vp-font-family-mono: /* code font */
}
```
:::warning
如果你在使用像是[团队页](/reference/default-theme-team-page)这样的组件,请确保也在从 `vitepress/theme-without-fonts` 中导入它们!
:::
如果你的字体是通过 `@font-face` 引用的本地文件,它将会被作为资源被包含在 `.vitepress/dist/asset` 目录下,并且使用哈希后的文件名。为了预加载这个文件,请使用 [transformHead](/reference/site-config#transformhead) 构建钩子:
```js
// .vitepress/config.js
export default {
transformHead({ assets }) {
// adjust the regex accordingly to match your font
const myFontFile = assets.find(file => /font-name\.\w+\.woff2/)
if (myFontFile) {
return [
[
'link',
{
rel: 'preload',
href: myFontFile,
as: 'font',
type: 'font/woff2',
crossorigin: ''
}
]
]
}
}
}
```
## 注册全局组件 {#registering-global-components}
```js
// .vitepress/theme/index.js
import DefaultTheme from 'vitepress/theme'
export default {
extends: DefaultTheme,
enhanceApp(ctx) {
// register your custom global components
ctx.app.component('MyGlobalComponent' /* ... */)
}
}
```
因为我们使用 Vite你还可以利用 Vite 的 [glob 导入功能](https://cn.vitejs.dev/guide/features.html#glob-import)来自动注册一个组件目录。
## 布局插槽 {#layout-slots}
默认主题的 `<Layout/>` 组件有一些插槽,能够被用来在页面的特定位置注入内容。下面这个例子展示了将一个组件注入到大纲之前:
```js
// .vitepress/theme/index.js
import DefaultTheme from 'vitepress/theme'
import MyLayout from './MyLayout.vue'
export default {
...DefaultTheme,
// override the Layout with a wrapper component that
// injects the slots
Layout: MyLayout
}
```
```vue
<!--.vitepress/theme/MyLayout.vue-->
<script setup>
import DefaultTheme from 'vitepress/theme'
const { Layout } = DefaultTheme
</script>
<template>
<Layout>
<template #aside-outline-before>
My custom sidebar top content
</template>
</Layout>
</template>
```
你也可以使用渲染函数。
```js
// .vitepress/theme/index.js
import { h } from 'vue'
import DefaultTheme from 'vitepress/theme'
import MyComponent from './MyComponent.vue'
export default {
...DefaultTheme,
Layout() {
return h(DefaultTheme.Layout, null, {
'aside-outline-before': () => h(MyComponent)
})
}
}
```
默认主题布局的全部可用插槽如下:
- 当 `layout: 'doc'` (默认) 在 frontmatter 中被启用时:
- `doc-footer-before`
- `doc-before`
- `doc-after`
- `sidebar-nav-before`
- `sidebar-nav-after`
- `aside-top`
- `aside-bottom`
- `aside-outline-before`
- `aside-outline-after`
- `aside-ads-before`
- `aside-ads-after`
- 当 `layout: 'home'` 在 frontmatter 中被启用时:
- `home-hero-before`
- `home-hero-info`
- `home-hero-image`
- `home-hero-after`
- `home-features-before`
- `home-features-after`
- 当未找到页面 (404) 时:
- `not-found`
- 总是启用:
- `layout-top`
- `layout-bottom`
- `nav-bar-title-before`
- `nav-bar-title-after`
- `nav-bar-content-before`
- `nav-bar-content-after`
- `nav-screen-content-before`
- `nav-screen-content-after`
## 重写内部组件 {#overriding-internal-components}
你可以使用 Vite 的 [aliases](https://vitejs.dev/config/shared-options.html#resolve-alias) 来用你的自定义组件替换默认主题的组件:
```ts
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vitepress'
export default defineConfig({
vite: {
resolve: {
alias: [
{
find: /^.*\/VPNavBar\.vue$/,
replacement: fileURLToPath(
new URL('./components/CustomNavBar.vue', import.meta.url)
)
}
]
}
}
})
```
想要了解组件的确切名称请参考我们的[源代码](https://github.com/vuejs/vitepress/tree/main/src/client/theme-default/components)。因为组件是内部的,因此在小版本更迭中,它们名字改动的可能性很小。

@ -0,0 +1,48 @@
# Frontmatter {#frontmatter}
## 用法 {#usage}
VitePress 支持在所有 Markdown 文件中使用 YAML frontmatter并使用 [gray-matter](https://github.com/jonschlinkert/gray-matter) 解析。frontmatter 必须位于 Markdown 文件的顶部 (在任何元素之前,包括 `<script>` 标签),并且需要在三条虚线之间的采用有效的 YAML 格式。例如:
```md
---
title: Docs with VitePress
editLink: true
---
```
许多站点或默认主题配置选项在 frontmatter 中都有相应的选项。你可以使用 frontmatter 来覆盖当前页面的特定行为。详细信息请参见 [Frontmatter Config Reference](../reference/frontmatter-config)。
你还可以定义自己的 frontmatter 数据,以在页面上的动态 Vue 表达式中使用。
## 访问 Frontmatter 数据 {#accessing-frontmatter-data}
Frontmatter 数据可以通过特殊的 `$frontmatter` 全局变量来访问:
下面的例子展示了你应该如何在 Markdown 文件中使用它:
```md
---
title: Docs with VitePress
editLink: true
---
# {{ $frontmatter.title }} {#{{-$frontmatter.title-}}}
Guide content
```
你还可以使用 [`useData()`](../reference/runtime-api#usedata) 辅助函数在 `<script setup>` 中访问当前页面的 frontmatter。
## 其他 Frontmatter 格式 {#alternative-frontmatter-formats}
VitePress 也支持 JSON 格式的 frontmatter以花括号开始和结束
```json
---
{
"title": "Blogging Like a Hacker",
"editLink": true
}
---
```

@ -0,0 +1,186 @@
# 快速开始 {#getting-started}
## 在线尝试 {#try-it-online}
可以直接在 [StackBlitz](https://vitepress.new) 上进行在线尝试。
## 安装 {#installation}
### 前置知识 {#prerequisites}
- [Node.js](https://nodejs.org/) 16 及以上版本。
- 通过命令行界面 (CLI) 访问 VitePress 的终端。
- 支持 [Markdown](https://en.wikipedia.org/wiki/Markdown) 语法的编辑器。
- 推荐 [VSCode](https://code.visualstudio.com/) 及其[官方 Vue 扩展](https://marketplace.visualstudio.com/items?itemName=Vue.volar)。
VitePress 可以单独使用,也可以安装到现有项目中。在这两种情况下,都可以使用以下方式安装它:
::: code-group
```sh [npm]
$ npm install -D vitepress
```
```sh [pnpm]
$ pnpm add -D vitepress
```
```sh [yarn]
$ yarn add -D vitepress
```
:::
::: details 遇到了 missing peer deps 警告?
如果使用 PNPM会注意到对 `@docsearch/js` 的 missing peer deps 警告。这不会影响 VitePress 运行。如果希望禁止显示此警告,请将以下内容添加到 `package.json`
```json
"pnpm": {
"peerDependencyRules": {
"ignoreMissing": [
"@algolia/client-search"
]
}
}
```
:::
### 安装向导 {#setup-wizard}
VitePress 附带一个命令行设置向导,可以帮助你构建一个基本项目。安装后,通过运行以下命令启动向导:
::: code-group
```sh [npm]
$ npx vitepress init
```
```sh [pnpm]
$ pnpm exec vitepress init
```
:::
你将需要回答几个简单的问题:
<p>
<img src="./vitepress-init.png" alt="vitepress init screenshot" style="border-radius:8px">
</p>
:::tip Vue 作为
如果打算使用 Vue 组件或 API 进行自定义,还应该明确地将 `vue` 安装为 peer dependency。
:::
## 文件结构 {#file-structure}
如果你正在构建一个独立的 VitePress 站点,你可以在当前目录 (`./`) 中搭建站点。但是,如果在现有项目中与其他源代码一起安装 VitePress建议将站点搭建在嵌套目录 (例如 `./docs`) 中,以便它与项目的其余部分分开。
假设你选择在 `./docs` 中搭建 VitePress 项目,生成的文件结构应该是这样的:
```
.
├─ docs
│ ├─ .vitepress
│ │ └─ config.js
│ ├─ api-examples.md
│ ├─ markdown-examples.md
│ └─ index.md
└─ package.json
```
`docs` 目录作为 VitePress 站点的项目**根目录**。`.vitepress` 目录是 VitePress 配置文件、开发服务器缓存、构建输出和可选主题自定义代码的位置。
:::tip
默认情况下VitePress 将其开发服务器缓存存储在 `.vitepress/cache` 中,并将生产构建输出存储在 `.vitepress/dist` 中。如果使用 Git应该将它们添加到 `.gitignore` 文件中。也可以手动[配置](../reference/site-config#outdir)这些位置。
:::
### 配置文件 {#the-config-file}
配置文件 (`.vitepress/config.js`) 让你能够自定义 VitePress 站点的各个方面,最基本的选项是站点的标题和描述:
```js
// .vitepress/config.js
export default {
// site-level options
title: 'VitePress',
description: 'Just playing around.',
themeConfig: {
// theme-level options
}
}
```
还可以通过 `themeConfig` 选项配置主题的行为。有关所有配置选项的完整详细信息,请参见[配置参考](../reference/site-config)。
### 源文件 {#source-files}
`.vitepress` 目录之外的 Markdown 文件被视为**源文件**。
VitePress 使用 **基于文件的路由**:每个 `.md` 文件将在相同的路径被编译成为 `.html` 文件。例如,`index.md` 将会被编译成 `index.html`,可以在生成的 VitePress 站点的根路径 `/` 进行访问。
VitePress 还提供了生成简洁 URL、重写路径和动态生成页面的能力。这些将在[路由指南](./routing)中进行介绍。
## 运行 {#up-and-running}
该工具还应该将以下 npm 脚本注入到 `package.json` 中:
```json
{
...
"scripts": {
"docs:dev": "vitepress dev docs",
"docs:build": "vitepress build docs",
"docs:preview": "vitepress preview docs"
},
...
}
```
`docs:dev` 脚本将启动具有即时热更新的本地开发服务器。使用以下命令运行它:
::: code-group
```sh [npm]
$ npm run docs:dev
```
```sh [pnpm]
$ pnpm run docs:dev
```
```sh [yarn]
$ yarn docs:dev
```
:::
除了 npm 脚本,还可以直接调用 VitePress
::: code-group
```sh [npm]
$ npx vitepress dev docs
```
```sh [pnpm]
$ pnpm exec vitepress dev docs
```
:::
更多的命令行用法请参见 [CLI 参考](../reference/cli)。
开发服务应该会运行在 `http://localhost:5173`上。在浏览器中访问 URL 以查看新站点的运行情况吧!
## 下一步 {#what-s-next}
- 想要进一步了解 Markdown 文件是怎么映射到对应的 HTML请继续阅读[路由指南](./routing)。
- 要了解有关可以在页面上执行的操作的更多信息,例如编写 Markdown 内容或使用 Vue 组件,请参见指南的“编写”部分。一个很好的起点是了解 [Markdown 扩展](./markdown)。
- 要探索默认文档主题提供的功能,请查看[默认主题配置参考](../reference/default-theme-config)。
- 如果想进一步自定义站点的外观,参见[扩展默认主题](./extending-default-theme)或者[构建自定义主题](./custom-theme)。
- 文档成形以后,务必阅读[部署指南](./deploy)。

@ -0,0 +1,99 @@
# 国际化 {#internationalization}
要使用内置的 i18n (国际化) 功能,需要创建类似于下面的目录结构:
```
docs/
├─ es/
│ ├─ foo.md
├─ fr/
│ ├─ foo.md
├─ foo.md
```
然后在 `docs/.vitepress/config.ts` 中:
```ts
import { defineConfig } from 'vitepress'
export default defineConfig({
// shared properties and other top-level stuff...
locales: {
root: {
label: 'English',
lang: 'en'
},
fr: {
label: 'French',
lang: 'fr', // optional, will be added as `lang` attribute on `html` tag
link: '/fr/guide' // default /fr/ -- shows on navbar translations menu, can be external
// other locale specific properties...
}
}
})
```
下面的属性能够被每个 locale 覆盖 (包括 root)
```ts
interface LocaleSpecificConfig<ThemeConfig = any> {
lang?: string
dir?: string
title?: string
titleTemplate?: string | boolean
description?: string
head?: HeadConfig[] // will be merged with existing head entries, duplicate meta tags are automatically removed
themeConfig?: ThemeConfig // will be shallow merged, common stuff can be put in top-level themeConfig entry
}
```
有关自定义默认主题的文本占位符的信息,请参考 [`DefaultTheme.Config`](https://github.com/vuejs/vitepress/blob/main/types/default-theme.d.ts) 接口。不要在 locale 级别覆盖 `themeConfig.algolia``themeConfig.carbonAds`。想获取多语言查询的信息,请参考 [Algolia docs](../reference/default-theme-search#i18n)。
**提示:** 配置文件也可以存储在 `docs/.vitepress/config/index.ts`。你可以为每个语言环境创建一个配置文件,然后从 `index.ts` 合并并导出它们以更好的组织文件结构。
## 为本地化设置子目录 {#separate-directory-for-each-locale}
下面是一个组织良好的结构:
```
docs/
├─ en/
│ ├─ foo.md
├─ es/
│ ├─ foo.md
├─ fr/
├─ foo.md
```
但是VitePress 默认不会将 `/` 重定向到 `/en/`。你需要配置你的服务来实现这一点。例如,在使用 Netlify 时,你可以添加一个 `docs/public/_redirects` 文件,如下所示:
```
/* /es/:splat 302 Language=es
/* /fr/:splat 302 Language=fr
/* /en/:splat 302
```
**提示:** 如果使用上述的方法,你可以使用`nf_lang` cookie 来保存用户的语言选择。一个非常基础的方法是通过在自定义主题的 [setup](./custom-theme#using-a-custom-theme) 函数中注册一个侦听器:
```ts
// docs/.vitepress/theme/index.ts
import DefaultTheme from 'vitepress/theme'
export default {
...DefaultTheme,
setup() {
const { lang } = useData()
watchEffect(() => {
if (inBrowser) {
document.cookie = `nf_lang=${lang.value}; expires=Mon, 1 Jan 2024 00:00:00 UTC; path=/`
}
})
}
}
```
## RTL 支持 (实验性功能) {#rtl-support-experimental}
要支持 RTL需要在配置中指定 `dir: 'rtl'` 并且使用一些 RTLCSS PostCSS 插件,例如 <https://github.com/MohammadYounes/rtlcss>, <https://github.com/vkalinichev/postcss-rtl> 或者 <https://github.com/elchininet/postcss-rtlcss>。你需要配置 PostCSS 插件,使用 `:where([dir="ltr"])``:where([dir="rtl"])` 作为前缀,以防止 CSS 特异性问题。

@ -0,0 +1,332 @@
# markdown 基础语法 {#markdown-base}
## markdown-it 插件
通过[markdown-it 插件](https://www.npmjs.com/search?q=keywords:markdown-it-plugin),可以实现更多 markdown 功能。
### 使用
`doc/.vitepress/config.ts` 中引入使用
```js
import mdFootnote from 'markdown-it-footnote'
markdown: {
config: md => {
md.use(mdFootnote)
...
},
},
```
## 标题 {#title}
```md
# 一级标题
## 二级标题
### 三级标题
...
```
::: details 示例
### 三级标题
#### 四级标题
##### 五级标题
###### 六级标题
:::
##### 标题编号
```md
<!-- 要添加自定义标题ID请在与标题相同的行上用大括号括起该自定义ID。 -->
### My Great Heading {#custom-id}
```
## 字体
##### 加粗
```md
**加粗**
```
##### 斜体
```md
_斜体_
```
##### 斜体加粗
```md
**_斜体加粗_**
```
##### 删除线
```md
~~删除线~~
```
::: details 示例
**加粗**
_斜体_
**_斜体加粗_**
~~删除线~~
:::
## 引用
```md
> 这是引用的内容
>
> > 这是引用的内容
> >
> > > > > > 这是引用的内容
<!-- 引用可以嵌套 -->
```
::: details 示例
> 这是引用的内容
>
> > 这是引用的内容
> >
> > > > > > 这是引用的内容
:::
## 分割线
```md
---
---
可以在一行中使用三个或更多的 \* 、 - 或者 \_ 来添加分隔线
```
::: details 示例
---
:::
## 换行
```md
<p></p> 或者
<br>
```
## 链接
```md
<!--Markdown本身语法不支持链接在新页面中打开, VitePress 做了处理 -->
[链接文本](链接 'title')
[VitePressCN](https://vanchkong.github.io/VitePressCN 'Vite & Vue 驱动的静态站点生成器')
<!-- 要将URL或电子邮件地址快速转换为链接请将其括在尖括号中。在 VitePress 中无需次步操作即可自动转换为链接,如果你想禁用自动URL链接可以用 `` 包裹它 -->
<https://vanchkong.github.io/VitePressCN>
<fake@example.com>
<!-- 为了强调链接,请在方括号之前和圆括号之后添加星号。同上方字体用法 -->
```
::: details 示例
[VitePressCN](https://vanchkong.github.io/VitePressCN 'Vite & Vue 驱动的静态站点生成器')
<https://vanchkong.github.io/VitePressCN>
<fake@example.com>
**~~<https://vanchkong.github.io/VitePressCN>~~**
https://vanchkong.github.io/VitePressCN
`https://vanchkong.github.io/VitePressCN`
:::
## 图片
```md
![alt](图片地址 'title')
alt 就是显示在图片下面的文字,相当于对图片内容的解释。
title 是图片的标题,当鼠标移到图片上时显示的内容。
<!-- 图片可以被链接包裹 -->
```
::: details 示例
![vite](/logo.svg 'vite')
:::
## 列表 {#list}
##### 无序列表 {#unordered-list}
```md
<!-- 注意:序号跟内容之间要有空格 -->
<!-- 无序列表也可以用 * 替代 - -->
- 无序列表
- 无序列表
- 无序列表
- - 可以替换为 \* 或者 +
...
```
##### 有序列表 {#ordered-list}
```md
1. 有序列表
2. 有序列表
3. 有序列表
...
```
##### 任务列表
```md
<!-- 任务列表基于 mit 插件 markdown-it-task-lists 实现 -->
- [x] 任务列表
- [ ] 任务列表
- [ ] 任务列表
```
##### 嵌套列表
```md
1. 有序列表
- 无序列表
- 无序列表
2. 有序列表
- 无序列表
1. 有序列表
2. 有序列表
- 无序列表
```
::: details 示例
- 无序列表
- 无序列表
- 无序列表
---
1. 有序列表
2. 有序列表
3. 有序列表
---
1. 有序列表
- 无序列表
- 无序列表
2. 有序列表
---
- [x] 任务列表
- [ ] 任务列表
- [ ] 任务列表
---
- 无序列表
1. 有序列表
2. 有序列表
- 无序列表
:::
## 表格
```md
| 居左 | 居中 | 居右 |
| :--- | :--: | ---: |
| 内容 | 内容 | 内容 |
| 内容 | 内容 | 内容 |
```
::: details 示例
| 表头 | 表头 | 表头 |
| :------- | :------: | -------: |
| 居左内容 | 居中内容 | 居右内容 |
| 内容 | 内容 | 内容 |
:::
## 代码块
##### 单行代码块
```md
`单行代码块`
```
##### 多行代码块
````md
<!-- ```之后可以指定语言类型, ~~~ 可以替换 ``` -->
```md
多行代码块
多行代码块
```
````
::: details 示例
`单行代码块` `单行代码块` `单行代码块`
```md
多行代码块
多行代码块
```
:::
## 转义字符
要显示原义字符,否则将用于设置 Markdown 文档中的文本格式 `\`,请在字符前面添加反斜杠。
```md
\* 如果没有反斜杠,这将是无序列表中的项目符号。
- 如果没有反斜杠,这将是无序列表中的项目符号。
```
::: details 示例 \* 如果没有反斜杠,这将是无序列表中的项目符号。
- 如果没有反斜杠,这将是无序列表中的项目符号。
:::
## 脚注
```md
<!-- 脚注基于 mit 插件 markdown-it-footnote 实现 -->
<!-- 注解始终出现在页面最下方,即使注解下方仍有其他代码内容 -->
任意文字[^1]
[^1]:解释
```
任意文字[^1]
[^1]:解释

@ -0,0 +1,763 @@
# Markdown 扩展 {#markdown-extensions}
VitePress 带有内置的 Markdown 扩展。
## 标题锚点 {#header-anchors}
标题会自动应用锚点。可以使用 `markdown.anchor` 选项配置锚点的渲染。
### 自定义锚点 {#custom-anchors}
要为标题指定自定义锚标记,而不是使用自动生成的锚标记,请在标题中添加后缀:
```
# Using custom anchors {#my-anchor}
```
这允许你链接到标题 `#my-anchor` 而不是默认的 `#using-custom-anchors`
## 链接 {#links}
内部和外部链接都会被特殊处理。
### 内部链接 {#internal-links}
内部链接将转换为单页导航的路由链接。此外,子目录中包含的每个 `index.md` 都会自动转换为 `index.html`,并带有相应的 URL `/`
例如,给定以下目录结构:
```
.
├─ index.md
├─ foo
│ ├─ index.md
│ ├─ one.md
│ └─ two.md
└─ bar
├─ index.md
├─ three.md
└─ four.md
```
假设你现在处于 `foo/one.md` 文件中:
```md
[Home](/) <!-- sends the user to the root index.md -->
[foo](/foo/) <!-- sends the user to index.html of directory foo -->
[foo heading](./#heading) <!-- anchors user to a heading in the foo index file -->
[bar - three](../bar/three) <!-- you can omit extension -->
[bar - three](../bar/three.md) <!-- you can append .md -->
[bar - four](../bar/four.html) <!-- or you can append .html -->
```
### 页面后缀 {#page-suffix}
默认情况下,生成的页面和内部链接带有 `.html` 后缀。
### 外部链接 {#external-links}
外部链接带有 `target="_blank" rel="noreferrer"`
- [vuejs.org](https://vuejs.org)
- [VitePress on GitHub](https://github.com/vuejs/vitepress)
## Frontmatter {#frontmatter}
[YAML 格式的 frontmatter](https://jekyllrb.com/docs/front-matter/) 开箱即用:
```yaml
---
title: Blogging Like a Hacker
lang: en-US
---
```
此数据将可用于页面的其余部分,以及所有自定义和主题组件。
更多信息,参见 [Frontmatter](../reference/frontmatter-config)。
## GitHub 风格的表格 {#github-style-tables}
**输入**
```
| Tables | Are | Cool |
| ------------- | :-----------: | ----: |
| col 3 is | right-aligned | $1600 |
| col 2 is | centered | $12 |
| zebra stripes | are neat | $1 |
```
**输出**
| Tables | Are | Cool |
| ------------- | :-----------: | -----: |
| col 3 is | right-aligned | \$1600 |
| col 2 is | centered | \$12 |
| zebra stripes | are neat | \$1 |
## Emoji :tada:
**输入**
```
:tada: :100:
```
**输出**
:tada: :100:
这里你可以找到[所有支持的 emoji 列表](https://github.com/markdown-it/markdown-it-emoji/blob/master/lib/data/full.json)。
## 目录表 (TOC) {#table-of-contents}
**输入**
```
[[toc]]
```
**输出**
[[toc]]
可以使用 `markdown.toc` 选项配置 TOC 的呈现效果。
## 自定义容器 {#custom-containers}
自定义容器可以通过它们的类型、标题和内容来定义。
### 默认标题 {#default-title}
**输入**
```md
::: 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.
:::
```
**输出**
::: 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.
:::
### 自定义标题 {#custom-title}
可以通过在容器的“类型”之后附加文本来设置自定义标题。
**输入**
````md
::: danger STOP
Danger zone, do not proceed
:::
::: details Click me to view the code
```js
console.log('Hello, VitePress!')
```
:::
````
**输出**
::: danger STOP
Danger zone, do not proceed
:::
::: details Click me to view the code
```js
console.log('Hello, VitePress!')
```
:::
### `raw`
这是一个特殊的容器,可以用来防止与 VitePress 的样式和路由冲突。这在记录组件库时特别有用。你可能还想查看 [whyframe](https://whyframe.dev/docs/integrations/vitepress) 以获得更好的隔离。
**语法**
```md
::: raw
Wraps in a <div class="vp-raw">
:::
```
`vp-raw` class 也可以直接用于元素。样式隔离目前是可选的:
::: details
- 使用你喜欢的包管理器来安装需要的依赖项:
```sh
$ npm install -D postcss postcss-prefix-selector
```
- 创建 `docs/.postcssrc.cjs` 并将以下内容
```js
module.exports = {
plugins: {
'postcss-prefix-selector': {
prefix: ':not(:where(.vp-raw *))',
includeFiles: [/vp-doc\.css/],
transform(prefix, _selector) {
const [selector, pseudo = ''] = _selector.split(/(:\S*)$/)
return selector + prefix + pseudo
},
},
},
}
```
:::
## 代码块中的语法高亮 {#syntax-highlighting-in-code-blocks}
VitePress 使用 [Shiki](https://shiki.matsu.io/) 在 Markdown 代码块中使用彩色文本实现语法高亮。Shiki 支持多种编程语言。你需要做的就是将有效的语言别名附加到代码块的开头:
**输入**
````
```js
export default {
name: 'MyComponent',
// ...
}
```
````
````
```html
<ul>
<li v-for="todo in todos" :key="todo.id">
{{ todo.text }}
</li>
</ul>
```
````
**输出**
```js
export default {
name: 'MyComponent',
// ...
}
```
```html
<ul>
<li v-for="todo in todos" :key="todo.id">{{ todo.text }}</li>
</ul>
```
在 Shiki 的代码仓库中,可以找到[合法的编程语言列表](https://github.com/shikijs/shiki/blob/main/docs/languages.md)。
还可以全局配置中自定义语法高亮主题。有关详细信息,参见 [`markdown` 选项](../reference/site-config#markdown)得到更多信息。
## 在代码块中实现行高亮 {#line-highlighting-in-code-blocks}
**输入**
````
```js{4}
export default {
data () {
return {
msg: 'Highlighted!'
}
}
}
```
````
**输出**
```js{4}
export default {
data () {
return {
msg: 'Highlighted!'
}
}
}
```
除了单行之外,还可以指定多个单行、多行,或两者均指定:
- 多行:例如 `{5-8}`、`{3-10}`、`{10-17}`
- 多个单行:例如 `{4,7,9}`
- 多行与单行:例如 `{4,7-13,16,23-27,40}`
**输入**
````
```js{1,4,6-8}
export default { // Highlighted
data () {
return {
msg: `Highlighted!
This line isn't highlighted,
but this and the next 2 are.`,
motd: 'VitePress is awesome',
lorem: 'ipsum'
}
}
}
```
````
**输出**
```js{1,4,6-8}
export default { // Highlighted
data () {
return {
msg: `Highlighted!
This line isn't highlighted,
but this and the next 2 are.`,
motd: 'VitePress is awesome',
lorem: 'ipsum',
}
}
}
```
也可以使用 `// [!code hl]` 注释实现行高亮。
**输入**
````
```js
export default {
data () {
return {
msg: 'Highlighted!' // [!code hl]
}
}
}
```
````
**输出**
```js
export default {
data() {
return {
msg: 'Highlighted!', // [!code hl]
}
},
}
```
## 代码块中聚焦 {#focus-in-code-blocks}
在某一行上添加 `// [!code focus]` 注释将聚焦它并模糊代码的其他部分。
此外,可以使用 `// [!code focus:<lines>]` 定义要聚焦的行数。
**输入**
`!code` 后面只需要一个空格,为了展示原始的代码而不被实际渲染,这里有两个空格:
````
```js
export default {
data () {
return {
msg: 'Focused!' // [!code focus]
}
}
}
```
````
**输出**
```js
export default {
data() {
return {
msg: 'Focused!', // [!code focus]
}
},
}
```
## 代码块中的颜色差异 {#colored-diffs-in-code-blocks}
在某一行添加 `// [!code --]``// [!code ++]` 注释将会为该行创建 diff同时保留代码块的颜色。
**输入**
`!code` 后面只需要一个空格,为了展示原始的代码而不被实际渲染,这里有两个空格。
````
```js
export default {
data () {
return {
msg: 'Removed' // [!code --]
msg: 'Added' // [!code ++]
}
}
}
```
````
**输出**
```js
export default {
data () {
return {
msg: 'Removed' // [!code --]
msg: 'Added' // [!code ++]
}
}
}
```
## 高亮 “错误” 和 “警告” {#errors-and-warnings-in-code-blocks}
在某一行添加 `// [!code warning]``// [!code error]` 注释将会为该行相应的着色。
**输入**
`!code` 后面只需要一个空格,为了展示原始的代码而不被实际渲染,这里有两个空格。
````
```js
export default {
data () {
return {
msg: 'Error', // [!code error]
msg: 'Warning' // [!code warning]
}
}
}
```
````
**输出**
```js
export default {
data() {
return {
msg: 'Error', // [!code error]
msg: 'Warning', // [!code warning]
}
},
}
```
## 行号 {#line-numbers}
你可以通过以下配置为每个代码块启用行号:
```js
export default {
markdown: {
lineNumbers: true,
},
}
```
查看 [`markdown` 选项](../reference/site-config#markdown) 获取更多信息。
你可以在你的代码块中添加 `:line-numbers` / `:no-line-numbers` 标记来覆盖在配置中的设置。
**输入**
````md
```ts {1}
// line-numbers is disabled by default
const line2 = 'This is line 2'
const line3 = 'This is line 3'
```
```ts:line-numbers {1}
// line-numbers is enabled
const line2 = 'This is line 2'
const line3 = 'This is line 3'
```
````
**输出**
```ts {1}
// line-numbers is disabled by default
const line2 = 'This is line 2'
const line3 = 'This is line 3'
```
```ts:line-numbers {1}
// line-numbers is enabled
const line2 = 'This is line 2'
const line3 = 'This is line 3'
```
## 导入代码片段 {#import-code-snippets}
你可以通过下面的语法来从现有文件中导入代码片段:
```md
<<< @/filepath
```
此语法同时支持[行高亮](#line-highlighting-in-code-blocks)
```md
<<< @/filepath{highlightLines}
```
**输入**
```md
<<< @/snippets/snippet.js{2}
```
**Code file**
<<< @/snippets/snippet.js
**输出**
<<< @/snippets/snippet.js{2}
::: tip
`@` 的值对应于源代码根目录,默认情况下是 VitePress 项目根目录,除非配置了 `srcDir`
:::
你也可以使用 [VS Code region](https://code.visualstudio.com/docs/editor/codebasics#_folding) 来只包含代码文件的相应部分。你可以在文件目录后面的 `#` 符号后提供一个自定义的区域名:
**输入**
```md
<<< @/snippets/snippet-with-region.js#snippet{1}
```
**Code file**
<<< @/snippets/snippet-with-region.js
**输出**
<<< @/snippets/snippet-with-region.js#snippet{1}
你也可以像这样在大括号内(`{}`)指定语言:
```md
<<< @/snippets/snippet.cs{c#}
<!-- with line highlighting: -->
<<< @/snippets/snippet.cs{1,2,4-6 c#}
<!-- with line numbers: -->
<<< @/snippets/snippet.cs{1,2,4-6 c#:line-numbers}
```
如果无法从文件拓展名推测出源语言,这将会很有帮助
## 代码组 {#code-groups}
你可以像这样对多个代码块进行分组:
**输入**
````md
::: code-group
```js [config.js]
/**
* @type {import('vitepress').UserConfig}
*/
const config = {
// ...
}
export default config
```
```ts [config.ts]
import type { UserConfig } from 'vitepress'
const config: UserConfig = {
// ...
}
export default config
```
:::
````
**输出**
::: code-group
```js [config.js]
/**
* @type {import('vitepress').UserConfig}
*/
const config = {
// ...
}
export default config
```
```ts [config.ts]
import type { UserConfig } from 'vitepress'
const config: UserConfig = {
// ...
}
export default config
```
:::
你也可以在代码组中[导入代码片段](#import-code-snippets)
**输入**
```md
::: code-group
<!-- filename is used as title by default -->
<<< @/snippets/snippet.js
<!-- you can provide a custom one too -->
<<< @/snippets/snippet-with-region.js#snippet{1,2 ts:line-numbers} [snippet with region]
:::
```
**输出**
::: code-group
<<< @/snippets/snippet.js
<<< @/snippets/snippet-with-region.js#snippet{1,2 ts:line-numbers} [snippet with region]
:::
## 包含 markdown 文件 {#markdown-file-inclusion}
你可以像这样在一个 markdown 文件中包含另一个 markdown 文件:
**输入**
```md
# Docs {#docs}
## Basics {#basics}
<!--@include: ./parts/basics.md-->
```
**另一个文件** (`parts/basics.md`)
```md
Some getting started stuff.
### Configuration {#configuration}
Can be created using `.foorc.json`.
```
**等价代码**
```md
# Docs {#docs}
## Basics {#basics}
Some getting started stuff.
### Configuration {#configuration}
Can be created using `.foorc.json`.
```
::: warning
注意!如果你指定的文件不存在,这将不会产生错误。因此,在使用这个功能的时候请保证内容按预期呈现。
:::
## 高级配置 {#advanced-configuration}
VitePress 使用 [markdown-it](https://github.com/markdown-it/markdown-it) 作为 Markdown 渲染器。上面提到的很多拓展功能都是通过自定义插件实现的。你可以使用 `.vitepress/config.js` 中的 `markdown` 选项来进一步自定义 `markdown-it` 实例。
```js
const anchor = require('markdown-it-anchor')
module.exports = {
markdown: {
// options for markdown-it-anchor
// https://github.com/valeriangalliat/markdown-it-anchor#usage
anchor: {
permalink: anchor.permalink.headerLink(),
},
// options for @mdit-vue/plugin-toc
// https://github.com/mdit-vue/mdit-vue/tree/main/packages/plugin-toc#options
toc: { level: [1, 2] },
config: (md) => {
// use more markdown-it plugins!
md.use(require('markdown-it-xxx'))
},
},
}
```
请查看[配置参考:站点配置](../reference/site-config#markdown)来获取完整的可配置属性列表。

@ -0,0 +1,23 @@
# 从 VitePress 0.x 迁移 {#migration-from-vitepress-0-x}
如果你来自 VitePress 0.x 版本由于新功能和增强功能VitePress 有了一些重大更改。 请按照本指南了解如何将你的应用程序迁移到最新的 VitePress。
## 应用配置 {#app-config}
- The internationalization feature is not yet implemented.
## 主题配置 {#theme-config}
- `sidebar` 选项改变了它的结构。
- `children` 现在命名为 `items`
- 顶级侧边栏不包含 `link`。 我们打算把它改回来。
- 删除了 `repo`、`repoLabel`、`docsDir`、`docsBranch`、`editLinks`、`editLinkText`以支持更灵活的api。
- 要将带有图标的 GitHub 链接添加到导航,请使用 [社交链接](../reference/default-theme-config#nav) 功能。
- 要添加“编辑此页面”功能,请使用 [编辑链接](../reference/default-theme-edit-link) 功能。
- `lastUpdated` 选项现在分为` config.lastUpdated` 和 `themeConfig.lastUpdatedText`
- `carbonAds.carbon` 更改为 `carbonAds.code`.
## Frontmatter 配置 {#frontmatter-config}
- `home: true` 选项已更改为 `layout: home`。此外,还修改了许多与主页相关的设置以提供附加功能。 详情请参阅 [主页指南](../reference/default-theme-home-page)。
- `footer` 选项移至 [`themeConfig.footer`](../reference/default-theme-footer).

@ -0,0 +1,30 @@
# 从 VuePress 迁移 {#migration-from-vuepress}
## 配置 {#config}
### 侧边栏 {#sidebar}
侧边栏不再从 frontmatter 中自动获取。 你可以自行阅读 [`frontmatter`](https://github.com/vuejs/vitepress/issues/572#issuecomment-1170116225) 来动态填充侧边栏。 [迁移工具](https://github.com/vuejs/vitepress/issues/96)将来可能会提供。
## Markdown {#markdown}
### 图片 {#images}
与 VuePress 不同在使用静态图片时VitePress 会根据你的配置自动处理这些 `base`(./asset-handling#base-url)。
因此,现在你可以在没有 `img` 标签的情况下渲染图像。
```diff
- <img :src="$withBase('/foo.png')" alt="foo">
+ ![foo](/foo.png)
```
::: warning 警告
对于动态图像,你仍然需要 `withBase`,如 [Base URL](./asset-handling#base-url) 中所示。
:::
使用 `<img.*withBase\('(.*)'\).*alt="([^"]*)".*>` 正则表达式查找并替换为 `![$2]($1)``![](...)` 语法替换所有图像。
---
更多请继续关注...

@ -0,0 +1,23 @@
# MPA 模式 <Badge type="warning" text="实验性的" /> {#mpa-mode}
可以通过命令行输入 `vitepress build --mpa` 或在配置文件中指定 `mpa: true` 配置选项来启用 MPA (Multi-Page Application) 模式。
在 MPA 模式下,所有页面都会默认不包含任何 JavaScript。因此站点可能评估工具中获得更好的初始访问性能分数。
但是,由于 SPA 导航的缺失跨页面链接将导致重新加载整个页面。MPA 模式下的导航不会像 SPA 模式那样立即响应。
同时请注意,默认情况下不使用 JavaScript 意味着你实际上只是将 Vue 作为服务器端模板语言。浏览器不会附加任何事件处理程序,因此将不会有任何交互性。要加载客户端 JavaScript你需要使用特殊的 `<script client>` 标签:
```html
<script client>
document.querySelector('h1').addEventListener('click', () => {
console.log('client side JavaScript!')
})
</script>
# Hello {#hello}
```
`<script client>` 是 VitePress 独有的功能,而不是 Vue 的功能。它可以在 `.md``.vue` 文件中使用,但只能在 MPA 模式下使用。所有主题组件中的客户端脚本将被打包在一起,而特定页面的客户端脚本将会分开处理。
请注意,`<script client>` **不会被视为 Vue 组件代码**:它会看做普通的 JavaScript 模块来处理。因此,只有在你的站点需要绝对最小的客户端交互性时,才应该使用 MPA 模式。

@ -0,0 +1,347 @@
---
outline: deep
---
# 路由 {#routing}
## 基于文件的路由 {#file-based-routing}
VitePress 使用基于文件的路由,这意味着生成的 HTML 页面是从源 Markdown 文件的目录结构映射而来的。例如,给定以下目录结构:
```
.
├─ guide
│ ├─ getting-started.md
│ └─ index.md
├─ index.md
└─ prologue.md
```
生成的 HTML 页面会是这样:
```
index.md --> /index.html (可以通过 / 访问)
prologue.md --> /prologue.html
guide/index.md --> /guide/index.html (可以通过 /guide/ 访问)
guide/getting-started.md --> /guide/getting-started.html
```
生成的 HTML 可以托管在任何可以提供静态文件的 Web 服务器上。
## 根目录和源目录 {#root-and-source-directory}
VitePress 项目的文件结构中有两个重要的概念:项目根目录 (**project root**) 和源目录 (**source directory**)。
### 项目根目录 {#project-root}
项目根目录是 VitePress 将尝试寻找 `.vitepress` 特殊目录的地方。 `.vitepress` 目录是 VitePress 配置文件、开发服务器缓存、构建输出和可选主题自定义代码的预留位置。
当你从命令行运行 `vitepress dev``vitepress build`VitePress 将使用当前工作目录作为项目根目录。要将子目录指定为根目录,你需要将相对路径传递给命令。例如,如果你的 VitePress 项目位于 `./docs`,你应该运行 `vitepress dev docs`
```
.
├─ docs # project root
│ ├─ .vitepress # config dir
│ ├─ getting-started.md
│ └─ index.md
└─ ...
```
```sh
vitepress dev docs
```
这将导致以下源代码到 HTML 的映射:
```
docs/index.md --> /index.html (可以通过 / 访问)
docs/getting-started.md --> /getting-started.html
```
### 源目录 {#source-directory}
源目录是你的 Markdown 源文件所在的位置。默认情况下,它与项目根目录相同。但是,你可以通过 [`srcDir`](../reference/site-config#srcdir) 配置选项对其进行配置。
`srcDir` 选项是相对于项目根目录解析的。例如,对于 `srcDir: 'src'`,你的文件结构将如下所示:
```
. # project root
├─ .vitepress # config dir
└─ src # source dir
├─ getting-started.md
└─ index.md
```
生成的源代码到 HTML 的映射:
```
src/index.md --> /index.html (可以通过 / 访问)
src/getting-started.md --> /getting-started.html
```
## 链接页面 {#linking-between-pages}
在页面之间链接时,你可以使用绝对路径和相对路径。请注意,虽然 `.md``.html` 扩展名都可以使用,但最佳做法是省略文件扩展名,以便 VitePress 可以根据你的配置生成最终 URL。
```md
<!-- 正确做法 -->
[Getting Started](./getting-started)
[Getting Started](../guide/getting-started)
<!-- 不正确做法 -->
[Getting Started](./getting-started.md)
[Getting Started](./getting-started.html)
```
在[资源处理](asset-handling)中了解有关链接到资源(例如图像)的更多信息。
## 生成简洁的 URL {#generating-clean-url}
:::warning 需要服务器支持
要使用 VitePress 提供简洁 URL需要服务器端支持。
:::
默认情况下VitePress 将入站链接解析为以 `.html` 结尾的 URL。但是一些用户可能更喜欢没有 .html 扩展名的“简洁 URL” —— 例如,`example.com/path` 而不是 `example.com/path.html`
某些服务器或托管平台(例如 Netlify 或 Vercel提供将 `/foo` 之类的 URL 映射到 `/foo.html`(如果存在)的功能,而无需重定向:
- Netlify 默认支持这个。
- Vercel 需要在 [vercel.json 中启用 cleanUrls 选项](https://vercel.com/docs/concepts/projects/project-configuration#cleanurls)。
如果你可以使用此功能,你还可以启用 VitePress 自己的 [`cleanUrls`](../reference/site-config#cleanurls) 配置选项,以便:
- 页面之间的入站链接是在没有 `.html` 扩展名的情况下生成的。
- 如果当前路径以 `.html` 结尾,路由器将执行客户端重定向到无扩展路径。
但是,如果你无法为服务器配置此类支持(例如 GitHub 页面),则必须手动采用以下目录结构:
```
.
├─ getting-started
│ └─ index.md
├─ installation
│ └─ index.md
└─ index.md
```
## 路由重写 {#route-rewrites}
你可以自定义源目录结构和生成页面之间的映射。当你有一个复杂的项目结构时,它很有用。例如,假设你有一个包含多个包的 monorepo并且希望将文档与源文件一起放置如下所示
```
.
├─ packages
│ ├─ pkg-a
│ │ └─ src
│ │ ├─ pkg-a-code.ts
│ │ └─ pkg-a-docs.md
│ └─ pkg-b
│ └─ src
│ ├─ pkg-b-code.ts
│ └─ pkg-b-docs.md
```
你希望像这样生成 VitePress 页面:
```
packages/pkg-a/src/pkg-a-docs.md --> /pkg-a/index.html
packages/pkg-b/src/pkg-b-docs.md --> /pkg-b/index.html
```
你可以通过像这样配置 [`rewrites`](../reference/site-config#rewrites) 选项来实现此目的:
```ts
// .vitepress/config.js
export default {
rewrites: {
'packages/pkg-a/src/pkg-a-docs.md': 'pkg-a/index.md',
'packages/pkg-b/src/pkg-b-docs.md': 'pkg-b/index.md',
},
}
```
`rewrites` 选项还支持动态路由参数。在上面的示例中,如果你有很多包,则列出所有路径会很冗长。鉴于它们都具有相同的文件结构,你可以像这样简化配置:
```ts
export default {
rewrites: {
'packages/:pkg/src/(.*)': ':pkg/index.md',
},
}
```
重写路径是使用 `path-to-regexp` 包编译的 - 请参阅[其文档](https://github.com/pillarjs/path-to-regexp#parameters)以获取更高级的语法。
:::warning 开启重写功能时使用相对链接
启用重写后,**相对链接应基于重写的路径**。例如,为了创建从 `packages/pkg-a/src/pkg-a-code.md``packages/pkg-b/src/pkg-b-code.md` 的相对链接,你应该使用:
```md
[Link to PKG B](../pkg-b/pkg-b-code)
```
:::
## 动态路由 {#dynamic-routes}
你可以使用单个 Markdown 文件和动态数据生成许多页面。例如,你可以创建一个 `packages/[pkg].md` 文件,为项目中的每个包生成相应的页面。这里,`[pkg]` 段是一个路由参数,用于区分每个页面。
### 路径加载文件 {#paths-loader-file}
由于 VitePress 是静态站点生成器,因此**必须**在构建时确定可能的页面路径。因此,动态路由页面必须伴随**路径加载文件**。对于 `packages/[pkg].md`,我们需要 `packages/[pkg].paths.js`(也支持 `.ts`
```
.
└─ packages
├─ [pkg].md # route template
└─ [pkg].paths.js # route paths loader
```
路径加载器应该提供一个带有 `paths` 方法的对象作为其默认导出。 `paths` 方法应返回具有 `params` 属性的对象数组。这些对象中的每一个都将生成一个相应的页面。
给定以下 `paths` 数组:
```js
// packages/[pkg].paths.js
export default {
paths() {
return [{ params: { pkg: 'foo' } }, { params: { pkg: 'bar' } }]
},
}
```
生成的 HTML 页面将会是:
```
.
└─ packages
├─ foo.html
└─ bar.html
```
### 多参数 {#multiple-params}
动态路由可以包含多个参数:
**File Structure**
```
.
└─ packages
├─ [pkg]-[version].md
└─ [pkg]-[version].paths.js
```
**路径加载器**
```js
export default {
paths: () => [
{ params: { pkg: 'foo', version: '1.0.0' } },
{ params: { pkg: 'foo', version: '2.0.0' } },
{ params: { pkg: 'bar', version: '1.0.0' } },
{ params: { pkg: 'bar', version: '2.0.0' } },
],
}
```
**输出**
```
.
└─ packages
├─ foo-1.0.0.html
├─ foo-2.0.0.html
├─ bar-1.0.0.html
└─ bar-2.0.0.html
```
### 动态生成路径 {#dynamically-generating-paths}
路径加载器模块在 Node.js 中运行,并且仅在构建期间执行。你可以使用本地或远程的任何数据动态生成路径数组。
从本地文件生成路径:
```js
import fs from 'fs'
export default {
paths() {
return fs.readdirSync('packages').map((pkg) => {
return { params: { pkg } }
})
},
}
```
从远程数据生成路径:
```js
export default {
async paths() {
const pkgs = await (await fetch('https://my-api.com/packages')).json()
return pkgs.map((pkg) => {
return {
params: {
pkg: pkg.name,
version: pkg.version,
},
}
})
},
}
```
### 访问页面中的参数 {#accessing-params-in-page}
你可以使用参数将附加数据传递到每个页面。 Markdown 路由文件可以通过 `$params` 全局属性访问 Vue 表达式中的当前页面参数:
```md
- package name: {{ $params.pkg }}
- version: {{ $params.version }}
```
你还可以通过 [`useData`](../reference/runtime-api#usedata) runtime API 访问当前页面的参数。这在 Markdown 文件和 Vue 组件中都可用:
```vue
<script setup>
import { useData } from 'vitepress'
// params is a Vue ref
const { params } = useData()
console.log(params.value)
</script>
```
### 渲染原始内容 {#rendering-raw-content}
传递给页面的参数将在客户端 JavaScript payload 中序列化,因此你应该避免在参数中传递大量数据,例如从远程 CMS 获取的原始 Markdown 或 HTML 内容。
相反,你可以使用每个路径对象上的 `content` 属性将此类内容传递到每个页面:
```js
export default {
paths() {
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 // raw Markdown or HTML
}
})
}
}
}
```
然后,使用以下特殊语法将内容呈现为 Markdown 文件本身的一部分:
```md
<!-- @content -->
```

@ -0,0 +1,119 @@
---
outline: deep
---
# SSR 兼容性 {#ssr-compatibility}
通过使用 Vue 的服务器端渲染 (SSR) 功能VitePress 能够在生产构建期间在 Node.js 中预渲染应用程序。这意味着主题组件中的所有自定义代码都需要考虑 SSR 兼容性。
[Vue 官方文档的 SSR 部分](https://cn.vuejs.org/guide/scaling-up/ssr.html)提供了更多有关 SSR 是什么SSR / SSG 之间的关系以及编写 SSR 友好代码的常见注意事项等信息。原则上只在 Vue 组件的 `beforeMount``mounted` 钩子中访问 browser / DOM API。
## `<ClientOnly>`
如果你正在使用或演示不支持 SSR 的组件 (例如,包含自定义指令),则可以将它们包装在内置的 `<ClientOnly>` 组件中:
```md
<ClientOnly>
<NonSSRFriendlyComponent />
</ClientOnly>
```
## 在导入时访问浏览器 API 的库 {#libraries-that-access-browser-api-on-import}
一些组件或库在**导入时**访问浏览器 API。要使用假定在导入时处于浏览器环境的代码你需要动态导入它们。
### 在 mounted 钩子中导入 {#importing-in-mounted-hook}
```vue
<script setup>
import { onMounted } from 'vue'
onMounted(() => {
import('./lib-that-access-window-on-import').then((module) => {
// use code
})
})
</script>
```
### 条件导入 {#conditional-import}
你也可以使用 `import.meta.env.SSR` 标志 ([Vite 环境变量](https://cn.vitejs.dev/guide/env-and-mode.html#env-变量)的一部分) 来有条件地导入依赖项:
```js
if (!import.meta.env.SSR) {
import('./lib-that-access-window-on-import').then((module) => {
// use code
})
}
```
因为 [`Theme.enhanceApp`](/guide/custom-theme#theme-interface) 可以是异步的,所以你可以有条件地导入并注册访问浏览器 API 的 Vue 插件:
```js
// .vitepress/theme/index.js
export default {
// ...
async enhanceApp({ app }) {
if (!import.meta.env.SSR) {
const plugin = await import('plugin-that-access-window-on-import')
app.use(plugin)
}
},
}
```
### `defineClientComponent` {#`defineclientcomponent`}
VitePress 为导入 Vue 组件提供了一个方便的辅助函数,该组件可以在导入时访问浏览器 API。
```vue
<script setup>
import { defineClientComponent } from 'vitepress'
const ClientComp = defineClientComponent(() => {
return import('component-that-access-window-on-import')
})
</script>
<template>
<ClientComp />
</template>
```
你还可以将 props/children/slots 传递给目标组件:
```vue
<script setup>
import { ref } from 'vue'
import { defineClientComponent } from 'vitepress'
const clientCompRef = ref(null)
const ClientComp = defineClientComponent(
() => import('component-that-access-window-on-import'),
// args are passed to h() - https://vuejs.org/api/render-function.html#h
[
{
ref: clientCompRef,
},
{
default: () => 'default slot',
foo: () => h('div', 'foo'),
bar: () => [h('span', 'one'), h('span', 'two')],
},
],
// callback after the component is loaded, can be async
() => {
console.log(clientCompRef.value)
},
)
</script>
<template>
<ClientComp />
</template>
```
目标组件只会在包装组件的 mounted 钩子中导入。

@ -0,0 +1,252 @@
# 在 Markdown 使用 Vue {#using-vue-in-markdown}
在 VitePress 中,每个 Markdown 文件都被编译成 HTML而且将其作为 [Vue 单文件组件](https://cn.vuejs.org/guide/scaling-up/sfc.html)处理。这意味着可以在 Markdown 中使用任何 Vue 功能,包括动态模板、使用 Vue 组件或通过添加 `<script>` 标签为页面的 Vue 组件添加逻辑。
值得注意的是VitePress 利用 Vue 的编译器自动检测和优化 Markdown 内容的纯静态部分。静态内容被优化为单个占位符节点,并从页面的 JavaScript 负载中删除以供初始访问。在客户端激活期间也会跳过它们。简而言之,你只需注意任何给定页面上的动态部分。
:::tip SSR 兼容性
所有的 Vue 用法都需要兼容 SSR。参阅 [SSR 兼容性](./ssr-compat)获得更多信息和常见的解决方案。
:::
## 模板化 {#templating}
### 插值语法 {#interpolation}
每个 Markdown 文件首先被编译成 HTML然后作为 Vue 组件传递给 Vite 流程管道。这意味着可以在文本中使用 Vue 的插值语法:
**输入**
```md
{{ 1 + 1 }}
```
**输出**
<div class="language-text"><pre><code>{{ 1 + 1 }}</code></pre></div>
### 指令 {#directives}
也可以使用指令 (请注意,根据设计,原始 HTML 在 Markdown 中也有效):
**输入**
```html
<span v-for="i in 3">{{ i }}</span>
```
**输出**
<div class="language-text"><pre><code><span v-for="i in 3">{{ i }} </span></code></pre></div>
## `<script>``<style>` {#script-and-style}
Markdown 文件中的根级 `<script>``<style>` 标签与 Vue SFC 中的一样,包括 `<script setup>`、`<style module>` 等。这里的主要区别是没有 `<template>` 标签:所有其他根级内容都是 Markdown。另请注意所有标签都应放在 frontmatter **之后**
```html
---
hello: world
---
<script setup>
import { ref } from 'vue'
const count = ref(0)
</script>
## Markdown Content The count is: {{ count }}
<button :class="$style.button" @click="count++">Increment</button>
<style module>
.button {
color: red;
font-weight: bold;
}
</style>
```
:::warning 避免在 Markdown 中使用 `<style scoped>`
在 Markdown 中使用时,`<style scoped>` 需要为当前页面的每个元素添加特殊属性,这将显著增加页面的大小。当我们需要局部范围的样式时 `<style module>` 是首选。
:::
你还可以访问 VitePress 的运行时 API例如 [`useData` 辅助函数](../reference/runtime-api#usedata),它提供了当前页面的元数据:
**输入**
```html
<script setup>
import { useData } from 'vitepress'
const { page } = useData()
</script>
<pre>{{ page }}</pre>
```
**输出**
```json
{
"path": "/using-vue.html",
"title": "Using Vue in Markdown",
"frontmatter": {},
...
}
```
## 使用组件 {#using-components}
你可以直接在 Markdown 文件中导入和使用 Vue 组件。
### 在 Markdown 中导入组件 {#importing-in-markdown}
如果一个组件只被几个页面使用,建议在使用它们的地方显式导入它们。这使它们可以正确地进行代码拆分,并且仅在显示相关页面时才加载:
```md
<script setup>
import CustomComponent from '../../components/CustomComponent.vue'
</script>
# Docs
This is a .md using a custom component
<CustomComponent />
## More docs
...
```
### 注册全局组件 {#registering-components-globally}
如果一个组件要在大多数页面上使用,可以通过自定义 Vue 实例来全局注册它们。有关示例,请参见[扩展默认主题](./extending-default-theme#registering-global-components)中的相关部分。
::: warning 重要
确保自定义组件的名称包含连字符或采用 PascalCase。否则它将被视为内联元素并包裹在 `<p>` 标签内,这将导致 hydration mismatch因为 `<p>` 不允许将块元素放置在其中。
:::
### 在标题中使用组件 <ComponentInHeader /> {#using-components-in-headers}
可以在标题中使用 Vue 组件,但请注意以下语法之间的区别:
| Markdown | 输出的 HTML | 被解析的标题 |
| ------------------------------------------------------- | ----------------------------------------- | ------------- |
| <pre v-pre><code> # text &lt;Tag/&gt; </code></pre> | `<h1>text <Tag/></h1>` | `text` |
| <pre v-pre><code> # text \`&lt;Tag/&gt;\` </code></pre> | `<h1>text <code>&lt;Tag/&gt;</code></h1>` | `text <Tag/>` |
`<code>` 包裹的 HTML 将按原样显示,只有未包裹的 HTML 才会被 Vue 解析。
::: tip
输出 HTML 由 [Markdown-it](https://github.com/Markdown-it/Markdown-it) 完成,而解析的标题由 VitePress 处理 (并用于侧边栏和文档标题)。
:::
## 转义 {#escaping}
可以通过使用 `v-pre` 指令将它们包裹在 `<span>` 或其他元素中来转义 Vue 插值:
**输入**
```md
This <span v-pre>{{ will be displayed as-is }}</span>
```
**输出**
<div class="escape-demo">
<p>This <span v-pre>{{ will be displayed as-is }}</span></p>
</div>
也可以将整个段落包装在 `v-pre` 自定义容器中:
```md
::: v-pre
{{ This will be displayed as-is }}
:::
```
**输出**
<div class="escape-demo">
::: v-pre
{{ This will be displayed as-is }}
:::
</div>
## 代码块中不转义 {#unescape-in-code-blocks}
默认情况下,代码块是受到保护的,都会自动使用 `v-pre` 包装,因此内部不会处理任何 Vue 语法。要在代码块内启用 Vue 插值语法,可以在代码语言后附加 `-vue` 后缀,例如 `js-vue`
**输入**
````md
```js-vue
Hello {{ 1 + 1 }}
```
````
**输出**
```js-vue
Hello {{ 1 + 1 }}
```
请注意,这可能会阻止某些标记被语法正确高亮显示。
## 使用 CSS 预处理器 {#using-css-pre-processors}
VitePress [内置支持](https://cn.vitejs.dev/guide/features.html#css-pre-processors) CSS 预处理器:`.scss`、`.sass`、.`less`、`.styl` 和 `.stylus` 文件。无需为它们安装 Vite 专用插件,但必须安装相应的预处理器:
```
# .scss and .sass
npm install -D sass
# .less
npm install -D less
# .styl and .stylus
npm install -D stylus
```
然后你可以在 Markdown 和主题组件中使用以下内容:
```vue
<style lang="sass">
.title
font-size: 20px
</style>
```
## 使用 teleport 传递组件内容 {#using-teleports}
Vitepress 目前只有使用 teleport 传送到 body 的 SSG 支持。对于其他地方,可以将它们包裹在内置的 `<ClientOnly>` 组件中,或者通过 [postRender 钩子](../reference/site-config#postrender)将 teleport 标签注入到最终页面 HTML 中的正确位置。
<ModalDemo />
::: details
<<< @/components/ModalDemo.vue
:::
```md
<ClientOnly>
<Teleport to="#modal">
<div>
// ...
</div>
</Teleport>
</ClientOnly>
```
<script setup>
import ModalDemo from '../components/ModalDemo.vue'
</script>
<style>
.escape-demo {
border: 1px solid var(--vp-c-border);
border-radius: 8px;
padding: 0 20px;
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

@ -0,0 +1,57 @@
# VitePress 是什么? {#what-is-vitepress}
VitePress 是一个[静态站点生成器](https://en.wikipedia.org/wiki/Static_site_generator) (SSG)专为构建快速、以内容为中心的网站而设计。简而言之VitePress 获取用 Markdown 编写的源内容,对其应用主题,并生成可以轻松部署到任何地方的静态 HTML 页面。
<div class="tip custom-block" style="padding-top: 8px">
只是想尝试一下?跳到[快速开始](./getting-started)。
</div>
## 使用场景 {#use-cases}
- **文档**
VitePress 附带一个专为技术文档设计的默认主题,尤其是那些需要嵌入交互式演示的主题。它支持你正在阅读的这个页面,以及 [Vite](https://vitejs.dev/)、[Pinia](https://pinia.vuejs.org/)、[VueUse](https://vueuse.org/)、[Mermaid](https://mermaid.js.org/)、[Wikimedia Codex](https://doc.wikimedia.org/codex/latest/) 等文档。
[Vue.js 官方文档](https://vuejs.org/) 也是基于 VitePress 的。但是为了可以在不同的翻译文档之间共享,它自定义了自己的主题
- **博客、档案和营销网站**
VitePress 支持[完全的自定义主题](./custom-theme),具有标准 Vite + Vue 应用程序的开发体验。基于 Vite 构建还意味着可以直接利用其丰富生态系统中的 Vite 插件。此外VitePress 提供了灵活的 API 来[加载数据](./data-loading) (本地或远程),也可以[动态生成路由](./routing#dynamic-routes)。只要可以在构建时确定数据,就可以使用它来构建几乎任何东西。
[Vue.js 官方博客](https://blog.vuejs.org/) 是一个简单的博客页面,它根据本地内容生成其索引页面。
## 开发体验 {#developer-experience}
VitePress 旨在使用 Markdown 生成内容时提供出色的开发体验。
- **[Vite 驱动](https://cn.vitejs.dev/)**:即时服务器启动,始终立即反映(<100ms)编辑变化,无需重新加载页面。
- **[内置 Markdown 扩展](./markdown)**Frontmatter、表格、语法高亮……应有尽有。具体来说VitePress 提供了许多用于处理代码块的高级功能,使其真正成为技术文档的理想选择。
- **[Vue 增强的 Markdown](./using-vue)**:每个 Markdown 页面都是 Vue [单文件组件](https://cn.vuejs.org/guide/scaling-up/sfc.html),这要归功于 Vue 模板与 HTML 的 100% 语法兼容性。可以使用 Vue 模板语法或导入的 Vue 组件在静态内容中嵌入交互性。
## 性能 {#performance}
与许多传统的 SSG 不同VitePress 生成的网站实际上是一个[单页应用程序](https://en.wikipedia.org/wiki/Single-page_application) (SPA)。
- **快速初始加载**
对任何页面的初次访问都将提供静态的、预呈现的 HTML以实现极快的加载速度和最佳的 SEO。然后页面加载一个 JavaScript 包,将页面变成 Vue SPA (这被称为“激活”)。激活是非常快的:在 [PageSpeed Insights](https://pagespeed.web.dev/report?url=https%3A%2F%2Fvitepress.dev%2F) 上,典型的 VitePress 站点即使在网络速度较慢的低端移动设备上也能获得近乎完美的性能分数。
- **加载完成后可以快速切换**
更重要的是SPA 模型在首次加载后能够提升用户体验。用户在网站内导航时不会再触发整个页面的刷新。而是通过获取并动态更新新页面的内容来实现切换。VitePress还会自动预加载视口范围内链接对应的页面片段。这样一来大部分情况下用户在加载完成后就能立即浏览新页面。
- **高效的交互**
为了能够嵌入静态 Markdown 中的动态 Vue 部分,每个 Markdown 页面都被处理为 Vue 组件并编译成 JavaScript。这听起来可能效率低下但 Vue 编译器足够聪明,可以将静态和动态部分分开,从而最大限度地减少激活成本和有效负载大小。对于初始页面加载,静态部分会自动从 JavaScript 有效负载中删除,并在激活期间跳过。
## VuePress 用户怎么办? {#what-about-vuepress}
VitePress 灵感来源于 VuePress。最初的 VuePress 基于 Vue 2 和 webpack。借助 Vue 3 和 ViteVitePress 提供了更好的开发体验、更好的生产性能、更精美的默认主题和更灵活的自定义 API。
VitePress 和 VuePress 之间的 API 区别主要在于主题和定制。如果你使用的是带有默认主题的 VuePress 1迁移到 VitePress 应该相对简单。
VuePress 2 也投入了精力,它也支持 Vue 3 和 Vite与 VuePress 1 的兼容性更好。但是,并行维护两个 SSG 是难以持续的,因此 Vue 团队决定将重点放在 VitePress作为长期的主要 SSG 选择推荐。

@ -0,0 +1,32 @@
---
layout: home
title: VitePress
titleTemplate: 由 Vite 和 Vue 驱动的静态站点生成器
hero:
name: VitePress
text: 由 Vite 和 Vue 驱动的静态站点生成器
tagline: 简单、强大、快速。就是你想要的现代 SSG 框架!
actions:
- theme: brand
text: 认识 VitePress
link: /zh/guide/what-is-vitepress
- theme: alt
text: GitHub
link: https://github.com/vuejs/vitepress
features:
- icon: 📝
title: 专注内容
details: 只需 Markdown 即可轻松创建美观的文档站点。
- icon: <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32"><g fill="none"><path fill="url(#a)" d="m29.884 6.146-13.142 23.5a.714.714 0 0 1-1.244.005L2.096 6.148a.714.714 0 0 1 .746-1.057l13.156 2.352a.714.714 0 0 0 .253 0l12.881-2.348a.714.714 0 0 1 .752 1.05z"/><path fill="url(#b)" d="M22.264 2.007 12.54 3.912a.357.357 0 0 0-.288.33l-.598 10.104a.357.357 0 0 0 .437.369l2.707-.625a.357.357 0 0 1 .43.42l-.804 3.939a.357.357 0 0 0 .454.413l1.672-.508a.357.357 0 0 1 .454.414l-1.279 6.187c-.08.387.435.598.65.267l.143-.222 7.925-15.815a.357.357 0 0 0-.387-.51l-2.787.537a.357.357 0 0 1-.41-.45l1.818-6.306a.357.357 0 0 0-.412-.45z"/><defs><linearGradient id="a" x1="6" x2="235" y1="33" y2="344" gradientTransform="translate(1.34 1.894) scale(.07142)" gradientUnits="userSpaceOnUse"><stop stop-color="#41D1FF"/><stop offset="1" stop-color="#BD34FE"/></linearGradient><linearGradient id="b" x1="194.651" x2="236.076" y1="8.818" y2="292.989" gradientTransform="translate(1.34 1.894) scale(.07142)" gradientUnits="userSpaceOnUse"><stop stop-color="#FFEA83"/><stop offset=".083" stop-color="#FFDD35"/><stop offset="1" stop-color="#FFA800"/></linearGradient></defs></g></svg>
title: 享受 Vite 无可比拟的体验
details: 服务器即时启动,闪电般的热更新,还可以使用基于 Vite 生态的插件。
- icon: <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32"><path fill="#41b883" d="M24.4 3.925H30l-14 24.15L2 3.925h10.71l3.29 5.6 3.22-5.6Z"/><path fill="#41b883" d="m2 3.925 14 24.15 14-24.15h-5.6L16 18.415 7.53 3.925Z"/><path fill="#35495e" d="M7.53 3.925 16 18.485l8.4-14.56h-5.18L16 9.525l-3.29-5.6Z"/></svg>
title: 使用 Vue 自定义
details: 直接在 Markdown 中使用 Vue 语法和组件,或者使用 Vue 组件构建自定义主题。
- icon: 🚀
title: 速度真的很快!
details: 采用静态 HTML 实现快速的页面初次加载,使用客户端路由实现快速的页面切换导航。
---

@ -0,0 +1,74 @@
# 命令行接口 {#command-line-interface}
## `vitepress dev`
使用指定目录作为根目录来启动 VitePress 开发服务器。默认为当前目录。在当前目录下运行时也可以省略 `dev` 命令。
### 用法
```sh
# 从当前目录开始,省略 `dev`
vitepress
# 从子目录开始
vitepress dev [root]
```
### 选项
| 选项 | 说明 |
| --------------- | ------------------------------------------ |
| `--open [path]` | 启动时打开浏览器 (`boolean \| string`) |
| `--port <port>` | 指定端口 (`number`) |
| `--base <path>` | 公共基础路径 (default: `/`) (`string`) |
| `--cors` | 启用 CORS |
| `--strictPort` | 如果指定的端口已被占用则退出 (`boolean`) |
| `--force` | 强制优化程序忽略缓存并重新绑定 (`boolean`) |
## `vitepress build`
构建用于生产的 VitePress 站点。
### 用法 {#usage}
```sh
vitepress build [root]
```
### 选项 {#options}
| 选项 | 说明 |
| ------------------------------ | ------------------------------------------------------------------------------------------------- |
| `--mpa` (experimental) | 在没有客户端 hydration 的 [MPA 模式](../guide/mpa-mode) 下构建 (`boolean`) |
| `--base <path>` | 公共基础路径 (default: `/`) (`string`) |
| `--target <target>` | 转译目标 (default: `"modules"`) (`string`) |
| `--outDir <dir>` | 输出目录 (default: `.vitepress/dist`) (`string`) |
| `--minify [minifier]` | 启用/禁用压缩,或指定要使用的压缩程序 (default: `"esbuild"`) (`boolean \| "terser" \| "esbuild"`) |
| `--assetsInlineLimit <number>` | 静态资源 base64 内联阈值(以字节为单位) (default: `4096`) (`number`) |
## `vitepress preview`
在本地预览生产版本。
### 用法 {#usage-1}
```sh
vitepress preview [root]
```
### 选项 {#options-1}
| 选项 | 说明 |
| --------------- | -------------------------------------- |
| `--base <path>` | 公共基础路径 (default: `/`) (`string`) |
| `--port <port>` | 指定端口 (`number`) |
## `vitepress init`
在当前目录中启动[安装向导](../guide/getting-started#setup-wizard)。
### 用法
```sh
vitepress init
```

@ -0,0 +1,83 @@
# 标记 {#badge}
徽标可让你为标题添加状态。例如,指定部分的类型或支持的版本可能很有用。
## 用法 {#usage}
你可以使用全局组件 `Badge`
```html
### Title <Badge type="info" text="default" />
### Title <Badge type="tip" text="^1.9.0" />
### Title <Badge type="warning" text="beta" />
### Title <Badge type="danger" text="caution" />
```
上面的代码渲染如下:
### Title <Badge type="info" text="default" />
### Title <Badge type="tip" text="^1.9.0" />
### Title <Badge type="warning" text="beta" />
### Title <Badge type="danger" text="caution" />
## 自定义 `children` {#custom-children}
`<Badge>` 接受 `子节点`, 这将显示在徽标中。
```html
### Title <Badge type="info">custom element</Badge>
```
### Title <Badge type="info">custom element</Badge>
## 自定义不同类型徽标的背景色 {#customize-type-color}
你可以通过覆盖 css 变量 `background-color` 来自定义不同类型 `<Badge />` 的背景色。以下是默认值。
```css
:root {
--vp-badge-info-border: var(--vp-c-divider-light);
--vp-badge-info-text: var(--vp-c-text-2);
--vp-badge-info-bg: var(--vp-c-white-soft);
--vp-badge-tip-border: var(--vp-c-green-dimm-1);
--vp-badge-tip-text: var(--vp-c-green-darker);
--vp-badge-tip-bg: var(--vp-c-green-dimm-3);
--vp-badge-warning-border: var(--vp-c-yellow-dimm-1);
--vp-badge-warning-text: var(--vp-c-yellow-darker);
--vp-badge-warning-bg: var(--vp-c-yellow-dimm-3);
--vp-badge-danger-border: var(--vp-c-red-dimm-1);
--vp-badge-danger-text: var(--vp-c-red-darker);
--vp-badge-danger-bg: var(--vp-c-red-dimm-3);
}
.dark {
--vp-badge-info-border: var(--vp-c-divider-light);
--vp-badge-info-bg: var(--vp-c-black-mute);
--vp-badge-tip-border: var(--vp-c-green-dimm-2);
--vp-badge-tip-text: var(--vp-c-green-light);
--vp-badge-warning-border: var(--vp-c-yellow-dimm-2);
--vp-badge-warning-text: var(--vp-c-yellow-light);
--vp-badge-danger-border: var(--vp-c-red-dimm-2);
--vp-badge-danger-text: var(--vp-c-red-light);
}
```
## `<Badge>`
`<Badge>` 组件接受以下属性:
```ts
interface Props {
// When `<slot>` is passed, this value gets ignored.
text?: string
// Defaults to `tip`.
type?: 'info' | 'tip' | 'warning' | 'danger'
}
```

@ -0,0 +1,22 @@
# Carbon Ads {#carbon-ads}
VitePress 内置了对 [Carbon Ads](https://www.carbonads.net/) 的原生支持。通过在配置中定义 Carbon Ads 凭据VitePress 将在页面上显示广告。
```js
export default {
themeConfig: {
carbonAds: {
code: 'your-carbon-code',
placement: 'your-carbon-placement',
},
},
}
```
这些值用于调用 carbon CDN 脚本,如下所示。
```js
;`//cdn.carbonads.com/carbon.js?serve=${code}&placement=${placement}`
```
要了解有关 Carbon Ads 配置的更多信息,请访问 [Carbon Ads 网站](https://www.carbonads.net/)。

@ -0,0 +1,394 @@
# 默认主题配置 {#default-theme-config}
主题配置可让你自定义主题。 你可以通过将 `themeConfig` 添加到配置文件来定义主题配置:
```ts
export default {
lang: 'en-US',
title: 'VitePress',
description: 'Vite & Vue powered static site generator.',
// Theme related configurations.
themeConfig: {
logo: '/logo.svg',
nav: [...],
sidebar: { ... }
}
}
```
**此页面上记录的选项仅适用于默认主题**。不同的主题需要不同的主题配置。使用自定义主题时,主题配置对象将传递给主题,以便主题可以基于它作出不同表现。
## i18nRouting {#i18nrouting}
- key: `i18nRouting`
- Type: `boolean`
将本地语言更改为 `zh` 会将 URL 从 `/foo`(或 `/en/foo/`)更改为 `/zh/foo`。你可以通过将 `themeConfig.i18nRouting` 设置为 `false` 来禁用此行为。
## 图标 {#logo}
- key: `logo`
- Type: `ThemeableImage`
Logo file to display in nav bar, right before the site title. Accepts a path string, or an object to set a different logo for light/dark mode.
```ts
export default {
themeConfig: {
logo: '/logo.svg',
},
}
```
```ts
type ThemeableImage = string | { src: string; alt?: string } | { light: string; dark: string; alt?: string }
```
## 站点标题开关 {#sitetitle}
- key: `siteTitle`
- Type: `string | false`
你可以自定义此项以替换导航中的默认站点标题(应用配置中的 `title`)。 当设置为 `false` 时,导航中的标题将被禁用。 这在当你的 `logo` 已经包含网站标题文本时很有用。
```ts
export default {
themeConfig: {
siteTitle: 'Hello World',
},
}
```
## 导航栏 {#nav}
- key: `nav`
- Type: `NavItem`
导航菜单项的配置。 你可以在[默认主题: 导航栏](./default-theme-nav#navigation-links) 了解更多详情。
```js
export default {
themeConfig: {
nav: [
{ text: 'Guide', link: '/guide' },
{
text: 'Dropdown Menu',
items: [
{ text: 'Item A', link: '/item-1' },
{ text: 'Item B', link: '/item-2' },
{ text: 'Item C', link: '/item-3' },
],
},
],
},
}
```
```ts
type NavItem = NavItemWithLink | NavItemWithChildren
interface NavItemWithLink {
text: string
link: string
activeMatch?: string
target?: string
rel?: string
}
interface NavItemChildren {
text?: string
items: NavItemWithLink[]
}
interface NavItemWithChildren {
text?: string
items: (NavItemChildren | NavItemWithLink)[]
activeMatch?: string
}
```
## 侧边栏 {#sidebar}
- key: `sidebar`
- Type: `Sidebar`
侧边栏菜单项的配置。 你可以在[默认主题: 侧边栏](./default-theme-sidebar) 了解更多详情。
```js
export default {
themeConfig: {
sidebar: [
{
text: 'Guide',
items: [
{ text: 'Introduction', link: '/introduction' },
{ text: 'Getting Started', link: '/getting-started' },
...
]
}
]
}
}
```
```ts
export type Sidebar = SidebarItem[] | SidebarMulti
export interface SidebarMulti {
[path: string]: SidebarItem[]
}
export type SidebarItem = {
/**
* The text label of the item.
*/
text?: string
/**
* The link of the item.
*/
link?: string
/**
* The children of the item.
*/
items?: SidebarItem[]
/**
* If not specified, group is not collapsible.
*
* If `true`, group is collapsible and collapsed by default
*
* If `false`, group is collapsible but expanded by default
*/
collapsed?: boolean
}
```
## 大纲开关 {#aside}
- key: `aside`
- Type: `boolean`
- Default: `true`
- 每个页面可以通过 [frontmatter](./frontmatter-config#aside) 覆写
将此值设置为 `false` 可禁用 aside(大纲) 容器。
## 大纲层级 {#outline}
- key: `outline`
- Type: `number | [number, number] | 'deep' | false`
- Default: `2`
- 每个页面可以通过 [frontmatter](./frontmatter-config#outline) 覆写
配置在大纲中显示的标题级别。你可以通过传递一个数字来指定一个特定的级别,或者你可以通过传递一个包含下限和上限的元组来提供一个级别范围。当传递等于 `[2, 6]``deep` 时,除 `h1` 外,所有标题级别都显示在轮廓中。设置 `false` 以隐藏轮廓。
## 大纲标题 {#outlinetitle}
- key: `outlineTitle`
- Type: `string`
- Default: `On this page`
可用于自定义右侧边栏的标题(在大纲链接的顶部)。 这在用另一种语言编写文档时很有用。
```js
export default {
themeConfig: {
outlineTitle: 'In hac pagina',
},
}
```
## 社交链接 {#sociallinks}
- Type: `SocialLink[]`
你可以定义此选项以在导航栏中展示带有图标的社交帐户链接。
```js
export default {
themeConfig: {
socialLinks: [
{ icon: 'github', link: 'https://github.com/vuejs/vitepress' },
{ icon: 'twitter', link: '...' },
// You can also add custom icons by passing SVG as string:
{
icon: {
svg: '<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Dribbble</title><path d="M12...6.38z"/></svg>',
},
link: '...',
},
],
},
}
```
```ts
interface SocialLink {
icon: SocialLinkIcon
link: string
}
type SocialLinkIcon = 'discord' | 'facebook' | 'github' | 'instagram' | 'linkedin' | 'mastodon' | 'slack' | 'twitter' | 'youtube' | { svg: string }
```
## 页脚 {#footer}
- Type: `Footer`
页脚配置。 你可以添加 message 和 copyright。 由于设计原因,仅当页面不包含侧边栏时才会显示页脚。
```ts
export default {
themeConfig: {
footer: {
message: 'Released under the MIT License.',
copyright: 'Copyright © 2019-present Evan You',
},
},
}
```
```ts
export interface Footer {
message?: string
copyright?: string
}
```
## 编辑链接 {#editlink}
- Type: `EditLink`
- 每个页面可以通过 [frontmatter](./frontmatter-config#editlink) 覆写
编辑链接可让你显示链接以编辑 Git 管理服务(例如 GitHub 或 GitLab上的页面。 有关详细信息,请参阅 [默认主题:编辑链接](./default-theme-edit-link)。
```js
export default {
themeConfig: {
editLink: {
pattern: 'https://github.com/vuejs/vitepress/edit/main/docs/:path',
text: 'Edit this page on GitHub',
},
},
}
```
```ts
export interface EditLink {
pattern: string
text?: string
}
```
## 最近更新时间文本 {#lastupdatedtext}
- Type: `string`
- Default: `Last updated`
显示最近更新时间之前的前缀文本。
```ts
export default {
themeConfig: {
lastUpdatedText: 'Updated Date',
},
}
```
## algolia
- Type: `AlgoliaSearch`
支持使用 [Algolia DocSearch](https://docsearch.algolia.com/docs/what-is-docsearch) 搜索站点文档。在 [默认主题:搜索](./default-theme-search) 中了解更多信息。
```ts
export interface AlgoliaSearchOptions extends DocSearchProps {
locales?: Record<string, Partial<DocSearchProps>>
}
```
在[这里](https://github.com/vuejs/vitepress/blob/main/types/docsearch.d.ts)查看完整配置。
## carbonAds {#carbon-ads}
- Type: `CarbonAdsOptions`
一个配置即可展示 [Carbon Ads](https://www.carbonads.net/)。
```ts
export default {
themeConfig: {
carbonAds: {
code: 'your-carbon-code',
placement: 'your-carbon-placement',
},
},
}
```
```ts
export interface CarbonAdsOptions {
code: string
placement: string
}
```
Learn more in [Default Theme: Carbon Ads](./default-theme-carbon-ads)
## 翻页文案 {#docFooter}
- Type: `DocFooter`
可用于自定义出现在上一篇和下一篇链接上方的文本。 如果不是用英语编写文档,这很有帮助。
```js
export default {
themeConfig: {
docFooter: {
prev: 'Pagina prior',
next: 'Proxima pagina',
},
},
}
```
```ts
export interface DocFooter {
prev?: string
next?: string
}
```
## 暗模式开关标签 {#darkmodeswitchlabel}
- key: `darkModeSwitchLabel`
- Type: `string`
- Default: `Appearance`
可用于自定义深色模式开关标签。此标签仅显示在移动视图中。
## 侧边栏菜单标签 {#sidebarmenulabel}
- key: `sidebarMenuLabel`
- Type: `string`
- Default: `Menu`
可用于自定义侧边栏菜单标签。此标签仅显示在移动视图中。
## 返回顶部标签 {#returntotoplabel}
- key: `returnToTopLabel`
- Type: `string`
- Default: `Return to top`
可用于自定义返回顶部按钮的标签。此标签仅显示在移动视图中。
## 多语言菜单标签 {#langmenulabel}
- key: `langMenuLabel`
- Type: `string`
- Default: `Change language`
可用于自定义导航栏中语言切换按钮的 aria-label。这仅在你使用 [i18n](../guide/i18n) 时使用。

@ -0,0 +1,62 @@
# 编辑链接 {#edit-link}
## 全局配置 {#site-level-config}
编辑链接让你可以显示一个链接,以在 GitHub 或 GitLab 等 Git 管理服务上编辑页面。要启用它,请将 `themeConfig.editLink` 选项添加到你的配置中。
```js
export default {
themeConfig: {
editLink: {
pattern: 'https://github.com/vuejs/vitepress/edit/main/docs/:path',
},
},
}
```
`pattern` 选项定义链接的 URL 结构,并且 `:path` 将被替换为页面路径。
你还可以放置一个接受“relativePath(相对路径)”作为参数并返回 URL 字符串的纯函数。
```js
export default {
themeConfig: {
editLink: {
pattern: ({ relativePath }) => {
if (relativePath.startsWith('packages/')) {
return `https://github.com/acme/monorepo/edit/main/${relativePath}`
} else {
return `https://github.com/acme/monorepo/edit/main/docs/${relativePath}`
}
},
},
},
}
```
::: details 它不应该有副作用,也不应该访问其范围之外的任何东西,因为它将在浏览器中被序列化和执行。
It should not have side-effects nor access anything outside of its scope since it will be serialized and executed in the browser.
:::
默认情况下,这将在文档页面底部添加链接文本"Edit this page"。你可以通过定义 `text` 选项来自定义此文本。
```js
export default {
themeConfig: {
editLink: {
pattern: 'https://github.com/vuejs/vitepress/edit/main/docs/:path',
text: 'Edit this page on GitHub',
},
},
}
```
## Frontmatter 配置 {#frontmatter-config}
可以使用 frontmatter 上的 `editLink` 选项单独禁用某个页面的编辑链接:
```yaml
---
editLink: false
---
```

@ -0,0 +1,39 @@
# 页脚 {#footer}
配置好 `themeConfig.footer` VitePress 将在全局页面底部显示页脚。
```ts
export default {
themeConfig: {
footer: {
message: 'Released under the MIT License.',
copyright: 'Copyright © 2019-present Evan You',
},
},
}
```
```ts
export interface Footer {
// The message shown right before copyright.
message?: string
// The actual copyright text.
copyright?: string
}
```
上面的配置也支持 HTML 字符串。所以,例如,如果你想配置页脚文本有一些链接,你可以调整配置如下:
```ts
export default {
themeConfig: {
footer: {
message: 'Released under the <a href="https://github.com/vuejs/vitepress/blob/main/LICENSE">MIT License</a>.',
copyright: 'Copyright © 2019-present <a href="https://github.com/yyx990803">Evan You</a>',
},
},
}
```
请注意,当[侧边栏](./default-theme-sidebar)可见时,不会显示页脚。

@ -0,0 +1,151 @@
# 主页 {#home-page}
VitePress 默认主题提供了一个首页布局,你也可以在[此网站首页](../)看到。你可以通过 [frontmatter](./frontmatter-config) 指定 `layout: home` 在任何页面上使用它
```yaml
---
layout: home
---
```
但是,仅此选项不会有太大作用。你可以通过设置其他选项(例如 `hero``features`)向主页添加几个不同的预模板化。
## Hero 部分 {#hero-section}
Hero section 位于主页顶部。以下是配置 Hero 的方法。
```yaml
---
layout: home
hero:
name: VitePress
text: Vite & Vue powered static site generator.
tagline: Lorem ipsum...
image:
src: /logo.png
alt: VitePress
actions:
- theme: brand
text: Get Started
link: /guide/what-is-vitepress
- theme: alt
text: View on GitHub
link: https://github.com/vuejs/vitepress
---
```
```ts
interface Hero {
// The string shown top of `text`. Comes with brand color
// and expected to be short, such as product name.
name?: string
// The main text for the hero section. This will be defined
// as `h1` tag.
text: string
// Tagline displayed below `text`.
tagline?: string
// The image is displayed next to the text and tagline area.
image?: ThemeableImage
// Action buttons to display in home hero section.
actions?: HeroAction[]
}
type ThemeableImage = string | { src: string; alt?: string } | { light: string; dark: string; alt?: string }
interface HeroAction {
// Color theme of the button. Defaults to `brand`.
theme?: 'brand' | 'alt'
// Label of the button.
text: string
// Destination link of the button.
link: string
}
```
### 自定义 name 的颜色 {#customizing-the-name-color}
VitePress 通过 (`--vp-c-brand`) 设置 `name` 的颜色 .但是,你可以通过覆写 `--vp-home-hero-name-color` 变量来自定义此颜色。
```css
:root {
--vp-home-hero-name-color: blue;
}
```
你也可以通过组合 `--vp-home-hero-name-background` 来进一步自定义 `name` 为渐变色。
```css
:root {
--vp-home-hero-name-color: transparent;
--vp-home-hero-name-background: -webkit-linear-gradient(120deg, #bd34fe, #41d1ff);
}
```
## Features 部分 {#features-section}
在 Features section 你可以在 Hero section 之后列出任意数量的 Features。可以在 frontmatter 中配置 `features`
你可以为每个 feature 提供一个图标可以是表情符号或任何类型的图像。当配置的图标是图片svg, png, jpeg...)时,必须提供合适的宽度和高度的图标;你还可以在需要时配置其描述、固有大小以及深色和浅色主题下的不同表现。
```yaml
---
layout: home
features:
- icon: 🛠️
title: Simple and minimal, always
details: Lorem ipsum...
- icon:
src: /cool-feature-icon.svg
title: Another cool feature
details: Lorem ipsum...
- icon:
dark: /dark-feature-icon.svg
light: /light-feature-icon.svg
title: Another cool feature
details: Lorem ipsum...
---
```
```ts
interface Feature {
// Show icon on each feature box.
icon?: FeatureIcon
// Title of the feature.
title: string
// Details of the feature.
details: string
// Link when clicked on feature component. The link can
// be both internal or external.
//
// e.g. `guid/reference/default-theme-home-page` or `htttps://example.com`
link?: string
// Link text to be shown inside feature component. Best
// used with `link` option.
//
// e.g. `Learn more`, `Visit page`, etc.
linkText?: string
}
type FeatureIcon =
| string
| { src: string; alt?: string; width?: string; height: string }
| {
light: string
dark: string
alt?: string
width?: string
height: string
}
```

@ -0,0 +1,22 @@
# 最后更新 {#last-updated}
最近一条内容的更新时间会显示在页面右下角。要启用它,请将 `lastUpdated` 选项添加到你的配置中。
## 全局配置 {#site-level-config}
```js
export default {
lastUpdated: true
}
```
## Frontmatter 配置 {#frontmatter-config}
可以使用 frontmatter 上的 `lastUpdated` 选项单独禁用某个页面的最后更新展示:
```yaml
---
lastUpdated: false
---
```

@ -0,0 +1,43 @@
# 布局 {#layout}
你可以通过设置页面 [frontmatter](./frontmatter-config) 选项来选择页面布局。有 3 种布局选项 `doc``page``home`。如果未指定任何内容,则该页面将被视为 `doc` 页面。
```yaml
---
layout: doc
---
```
## doc 布局 {#doc-layout}
`doc` 是默认布局,它将整个 Markdown 内容设置为“documentation”外观。它的工作原理是将整个内容包装在 css `vp-doc` 类中,并将样式应用于它下面的元素。
几乎所有通用元素,例如 `p`, 或 `h2` 都有特殊的样式。因此,请记住,如果你在 Markdown 内容中添加任何自定义 HTML这些内容也会受到这些样式的影响。
它还提供下面列出的文档特定功能。这些功能仅在此布局中启用。
<!-- - Edit Link
- Prev Next Link
- Outline
- [Carbon Ads](./default-theme-carbon-ads) -->
- [编辑链接](./default-theme-edit-link)
- [上下页文本](./default-theme-prev-next-links)
- [大纲](./default-theme-config#outline)
- [Carbon Ads](./default-theme-carbon-ads)
## page 布局 {#page-layout}
`page` 被视为“空白页”。 Markdown 仍然会被解析,所有的 [Markdown 扩展](../guide/markdown) 都和 `doc` 布局一样运行,但它没有任何默认样式。
`page` 布局将使你可以自行设计所有内容,而不会受 VitePress 主题影响。当你想要创建自己的自定义页面时,这很有用。
请注意,即使在此布局中,如果页面具有匹配的侧边栏配置,侧边栏仍会显示。
## home 布局 {#home-layout}
`home` 将生成模板化的“主页”。在此布局中, 你可以设置额外的选项,例如 `hero``features` 以进一步自定义内容。请访问[默认主题: 主页](./default-theme-home-page)了解更多详情。
## 无布局 {#no-layout}
如果你不想要任何布局,你可以通过 frontmatter 传递 `layout: false`。如果你想要一个完全可自定义的登录页面(默认情况下没有任何侧边栏、导航栏或页脚),此选项很有用。

@ -0,0 +1,162 @@
# 导航栏 {#nav}
Nav 是显示在页面顶部的导航栏。它包含站点标题、全局菜单链接等。
## 网站标题和图标 {#site-title-and-logo}
默认情况下nav 显示 [`config.title`](./site-config#title) 作为站点的标题。如果你想更改导航栏上显示的内容,你可以在 `themeConfig.siteTitle` 选项中定义自定义文本。
```js
export default {
themeConfig: {
siteTitle: 'My Custom Title',
},
}
```
如果你的站点有图标,则可以通过传递图片路径来显示它。你应该将图标直接放在 `public` 中,并赋值该绝对路径。
```js
export default {
themeConfig: {
logo: '/my-logo.svg',
},
}
```
添加图标时,它会与站点标题一起显示。如果你只需要图标并且想要隐藏站点标题文本,请将 `siteTitle` 选项设置为 `false`
```js
export default {
themeConfig: {
logo: '/my-logo.svg',
siteTitle: false,
},
}
```
如果你想添加 `alt` 属性或根据暗/亮模式自定义它, 你还可以将图标作为对象传递。有关详细信息,请参阅 [`themeConfig.logo`](./default-theme-config#logo)。
## 导航链接 {#navigation-links}
你可以定义 `themeConfig.nav` 选项以将链接添加到你的导航栏。
```js
export default {
themeConfig: {
nav: [
{ text: 'Guide', link: '/guide' },
{ text: 'Config', link: '/config' },
{ text: 'Changelog', link: 'https://github.com/...' },
],
},
}
```
`text` 是 nav 中显示的实际文本,而 `link` 是单击文本时将导航到的链接。对于链接,将路径设置为不带 `.md` 后缀的实际文件,并且始终以 `/` 开头。
导航链接也可以是下拉菜单。为此,请替换 `link` 选项,设置 `items` 数组。
```js
export default {
themeConfig: {
nav: [
{ text: 'Guide', link: '/guide' },
{
text: 'Dropdown Menu',
items: [
{ text: 'Item A', link: '/item-1' },
{ text: 'Item B', link: '/item-2' },
{ text: 'Item C', link: '/item-3' },
],
},
],
},
}
```
请注意,下拉菜单标题(上例中的 `下拉菜单`)不能具有 `link` 属性,因为它是打开下拉对话框的按钮。
你还可以通过传入更多嵌套项来进一步向下拉菜单项添加“sections”。
```js
export default {
themeConfig: {
nav: [
{ text: 'Guide', link: '/guide' },
{
text: 'Dropdown Menu',
items: [
{
// 该部分的标题
text: 'Section A Title',
items: [
{ text: 'Section A Item A', link: '...' },
{ text: 'Section B Item B', link: '...' },
],
},
],
},
{
text: 'Dropdown Menu',
items: [
{
// 你也可以省略标题
items: [
{ text: 'Section A Item A', link: '...' },
{ text: 'Section B Item B', link: '...' },
],
},
],
},
],
},
}
```
### 自定义链接的路由匹配状态 {#customize-link-s-active-state}
当前页面位于匹配路径下时,导航菜单项将突出显示。如果 你想自定义要匹配的路径,请将 `activeMatch` 属性和正则表达式定义为字符串值。
```js
export default {
themeConfig: {
nav: [
// This link gets active state when the user is
// on `/config/` path.
{
text: 'Guide',
link: '/guide',
activeMatch: '/config/',
},
],
},
}
```
::: warning 警告
`activeMatch` 应为正则表达式字符串,但你必须将其定义为字符串。我们不能在这里使用实际的 RegExp 对象,因为它在构建期间不可序列化。
:::
### 自定义链接的“target”和“rel”属性 {#customize-link-s-target-and-rel-attributes}
默认情况下VitePress 会根据链接是否为外部链接自动判断 `target``rel` 属性。但如果你愿意,你也可以自定义它们。
```js
export default {
themeConfig: {
nav: [
{
text: 'Merchandise',
link: 'https://www.thegithubshop.com/',
target: '_self',
rel: 'sponsored',
},
],
},
}
```
## 社交链接 {#social-links}
参考 [`社交链接`](./default-theme-config#sociallinks)。

@ -0,0 +1,44 @@
# 上下页链接 {#prev-next-links}
你可以自定义上(下)一篇链接的文本。如果 你想在 上(下)一篇 链接上显示与侧边栏上不同的文本(默认显示侧边栏的文本),这将很有帮助。
你可以自定义上一页和下一页的文本和链接(显示在文档页脚处)。如果你想要的文本与边栏上的文本不同,这会很有帮助。此外,还可以禁用侧边栏中未包含页面的页脚或链接
## prev
- Type: `string | false | { text?: string; link?: string }`
- Details:
指定要在指向上一页的链接上显示的文本/链接。如果你没有在 `frontmatter` 中设置它,文本/链接将从侧边栏配置中推断出来。
- 示例:
- 仅自定义文本:
```yaml
---
prev: 'Get Started | Markdown'
---
```
- 自定义文本和链接:
```yaml
---
prev:
text: 'Markdown'
link: '/guide/markdown'
---
```
- 隐藏上一页:
```yaml
---
prev: false
---
```
## next
`prev` 相同,但用于下一页。

@ -0,0 +1,155 @@
# 搜索 {#search}
## 本地搜索 {#local-search}
得益于 [minisearch](https://github.com/lucaong/minisearch/)VitePress 支持使用浏览器内索引进行模糊全文搜索。
要启用此功能,只需在 `.vitepress/config.ts` 文件中将 `themeConfig.search.provider` 选项设置为 `'local'` 即可:
```ts
import { defineConfig } from 'vitepress'
export default defineConfig({
themeConfig: {
search: {
provider: 'local',
},
},
})
```
示例结果:
![搜索弹窗截图](/search.png)
或者,你可以使用 [Algolia DocSearch](#algolia-search) 或一些社区插件,例如:<https://www.npmjs.com/package/vitepress-plugin-search> 或者 <https://www.npmjs.com/package/vitepress-plugin-pagefind>
### i18n {#local-search-i18n}
你可以使用这样的配置来使用多语言搜索:
```ts
import { defineConfig } from 'vitepress'
export default defineConfig({
themeConfig: {
search: {
provider: 'local',
options: {
locales: {
zh: {
translations: {
button: {
buttonText: '搜索文档',
buttonAriaLabel: '搜索文档',
},
modal: {
noResultsText: '无法找到相关结果',
resetButtonTitle: '清除查询条件',
footer: {
selectText: '选择',
navigateText: '切换',
},
},
},
},
},
},
},
},
})
```
## Algolia Search {#algolia-search}
VitePress 支持使用 [Algolia DocSearch](https://docsearch.algolia.com/docs/what-is-docsearch) 搜索你的文档站点。请参阅他们的入门指南。在你的 `.vitepress/config.ts` 中,你至少需要提供以下内容才能使其正常工作:
```ts
import { defineConfig } from 'vitepress'
export default defineConfig({
themeConfig: {
search: {
provider: 'algolia',
options: {
appId: '...',
apiKey: '...',
indexName: '...',
},
},
},
})
```
### i18n {#algolia-search-i18n}
你可以使用这样的配置来使用多语言搜索:
```ts
import { defineConfig } from 'vitepress'
export default defineConfig({
// ...
themeConfig: {
search: {
provider: 'algolia',
options: {
appId: '...',
apiKey: '...',
indexName: '...',
locales: {
zh: {
placeholder: '搜索文档',
translations: {
button: {
buttonText: '搜索文档',
buttonAriaLabel: '搜索文档',
},
modal: {
searchBox: {
resetButtonTitle: '清除查询条件',
resetButtonAriaLabel: '清除查询条件',
cancelButtonText: '取消',
cancelButtonAriaLabel: '取消',
},
startScreen: {
recentSearchesTitle: '搜索历史',
noRecentSearchesText: '没有搜索历史',
saveRecentSearchButtonTitle: '保存至搜索历史',
removeRecentSearchButtonTitle: '从搜索历史中移除',
favoriteSearchesTitle: '收藏',
removeFavoriteSearchButtonTitle: '从收藏中移除',
},
errorScreen: {
titleText: '无法获取结果',
helpText: '你可能需要检查你的网络连接',
},
footer: {
selectText: '选择',
navigateText: '切换',
closeText: '关闭',
searchByText: '搜索提供者',
},
noResultsScreen: {
noResultsText: '无法找到相关结果',
suggestedQueryText: '你可以尝试查询',
reportMissingResultsText: '你认为该查询应该有结果?',
reportMissingResultsLinkText: '点击反馈',
},
},
},
},
},
},
},
},
})
```
[这些选项](https://github.com/vuejs/vitepress/blob/main/types/docsearch.d.ts)可以被覆盖。请参阅官方 Algolia 文档以了解更多信息。
<style>
img[src="/search.png"] {
width: 100%;
aspect-ratio: 1 / 1;
}
</style>

@ -0,0 +1,182 @@
# 侧边栏 {#sidebar}
侧边栏是文档的主要导航块。 你可以在 [`themeConfig.sidebar`](./default-theme-config#sidebar) 中配置侧边栏菜单。
```js
export default {
themeConfig: {
sidebar: [
{
text: 'Guide',
items: [
{ text: 'Introduction', link: '/introduction' },
{ text: 'Getting Started', link: '/getting-started' },
...
]
}
]
}
}
```
## 基本用法 {#the-basics}
侧边栏菜单的最简单形式是传入一个链接数组。第一级项目定义侧边栏的“部分”。它应该包含作为小标题的 `text` 和作为实际导航链接的 `items`
```js
export default {
themeConfig: {
sidebar: [
{
text: 'Section Title A',
items: [
{ text: 'Item A', link: '/item-a' },
{ text: 'Item B', link: '/item-b' },
...
]
},
{
text: 'Section Title B',
items: [
{ text: 'Item C', link: '/item-c' },
{ text: 'Item D', link: '/item-d' },
...
]
}
]
}
}
```
每个 `link` 都应指定以 `/` 开头的实际文件的路径。如果在链接末尾添加斜杠,它将显示相应目录的 `index.md`
```js
export default {
themeConfig: {
sidebar: [
{
text: 'Guide',
items: [
// This shows `/guide/index.md` page.
{ text: 'Introduction', link: '/guide/' },
],
},
],
},
}
```
你可以进一步将侧边栏项目嵌入到 6 级深度,从根级别上计数。请注意,深度超过 6 级嵌套物品被忽略,并且不会在侧边栏上显示。
```js
export default {
themeConfig: {
sidebar: [
{
text: 'Level 1',
items: [
{
text: 'Level 2',
items: [
{
text: 'Level 3',
items: [
...
]
}
]
}
]
}
]
}
}
```
## 多侧边栏 {#multiple-sidebars}
你可能会根据页面路径显示不同的侧边栏。例如,如本网站所示,你可能希望在文档中创建单独的侧边栏,例如“指引”页面和“配置参考”页面。
为此,首先将你的页面组织到每个所需部分的目录中:
```
.
├─ guide/
│ ├─ index.md
│ ├─ one.md
│ └─ two.md
└─ config/
├─ index.md
├─ three.md
└─ four.md
```
然后,更新你的配置以定义每个部分的侧边栏。这一次,你应该传递一个对象而不是数组。
```js
export default {
themeConfig: {
sidebar: {
// This sidebar gets displayed when a user
// is on `guide` directory.
'/guide/': [
{
text: 'Guide',
items: [
{ text: 'Index', link: '/guide/' },
{ text: 'One', link: '/guide/one' },
{ text: 'Two', link: '/guide/two' },
],
},
],
// This sidebar gets displayed when a user
// is on `config` directory.
'/config/': [
{
text: 'Config',
items: [
{ text: 'Index', link: '/config/' },
{ text: 'Three', link: '/config/three' },
{ text: 'Four', link: '/config/four' },
],
},
],
},
},
}
```
## 可折叠的侧边栏组 {#collapsible-sidebar-groups}
通过向侧边栏组添加 `collapsed` 选项,它会显示一个切换按钮来隐藏/显示每个部分。
```js
export default {
themeConfig: {
sidebar: [
{
text: 'Section Title A',
collapsed: false,
items: [...]
}
]
}
}
```
默认情况下,所有部分都是“打开”的。如果 你希望它们在初始页面加载时“关闭”,请将 `collapsed` 选项设置为 `true`
```js
export default {
themeConfig: {
sidebar: [
{
text: 'Section Title A',
collapsed: true,
items: [...]
}
]
}
}
```

@ -0,0 +1,254 @@
<script setup>
import { VPTeamMembers } from 'vitepress/theme'
const members = [
// {
// avatar: 'https://github.com/yyx990803.png',
// name: 'Evan You',
// title: 'Creator',
// links: [
// { icon: 'github', link: 'https://github.com/yyx990803' },
// { icon: 'twitter', link: 'https://twitter.com/youyuxi' }
// ]
// },
// {
// avatar: 'https://github.com/kiaking.png',
// name: 'Kia King Ishii',
// title: 'Developer',
// links: [
// { icon: 'github', link: 'https://github.com/kiaking' },
// { icon: 'twitter', link: 'https://twitter.com/KiaKing85' }
// ]
// }
{
avatar: 'https://avatars.githubusercontent.com/u/50388827?v=4',
name: 'VanchKong',
title: 'Translator',
links: [
{ icon: 'github', link: 'https://github.com/vanchKong' },
]
}
]
</script>
# 团队页 {#team-page}
如果你想介绍你的团队,你可以使用 Team components 来构建团队页面。有两种使用这些组件的方法。一种是将其嵌入文档页面,另一种是创建完整的团队页面。
## 在页面中显示团队成员 {#show-team-members-in-a-page}
你可以在任何页面上使用从 `vitepress/theme` 暴露出的公共组件 `<VPTeamMembers>` 显示团队成员。
```html
<script setup>
import { VPTeamMembers } from 'vitepress/theme'
const members = [
{
avatar: 'https://www.github.com/yyx990803.png',
name: 'Evan You',
title: 'Creator',
links: [
{ icon: 'github', link: 'https://github.com/yyx990803' },
{ icon: 'twitter', link: 'https://twitter.com/youyuxi' }
]
},
...
]
</script>
# 我们的团队,向我们出色的团队问好。
<VPTeamMembers size="small" :members="members" />
```
以上将在卡片外观元素中显示团队成员。它应该显示类似于下面的内容。
<VPTeamMembers size="small" :members="members" />
`<VPTeamMembers>` 组件有 2 种不同的尺寸, `small``medium`。虽然它取决于为你的偏好,但通常尺寸在文档页面中使用时 `small` 应该更适合。此外,你可以为每个成员添加更多属性,例如添加“描述”或“赞助”按钮。在 [`<VPTeamMembers>`](#vpteammembers)中了解更多信息。
在文档页面中嵌入团队成员对于小型团队来说非常有用,某种情况下,完整的贡献团队可能太大了,可以引入部分成员作为文档上下文的参考。
如果你有大量成员,或者只是想有更多空间来展示团队成员,请考虑[创建一个完整的团队页面](#create-a-full-team-page)。
## 创建一个完整的团队页面 {#create-a-full-team-page}
除了将团队成员添加到 doc 页面,你还可以创建一个完整的团队页面,类似于创建自定义[默认主题:主页](./default-theme-home-page)的方式。
要创建团队页面,首先,创建一个新的 md 文件。文件名无所谓,这里我们就叫它 `team.md` 吧。在这个文件中,在 frontmatter 设置 `layout: page`,然后你可以使用 `TeamPage` 组件来组成你的页面结构。
```html
---
layout: page
---
<script setup>
import {
VPTeamPage,
VPTeamPageTitle,
VPTeamMembers
} from 'vitepress/theme'
const members = [
{
avatar: 'https://www.github.com/yyx990803.png',
name: 'Evan You',
title: 'Creator',
links: [
{ icon: 'github', link: 'https://github.com/yyx990803' },
{ icon: 'twitter', link: 'https://twitter.com/youyuxi' }
]
},
...
]
</script>
<VPTeamPage>
<VPTeamPageTitle>
<template #title> Our Team </template>
<template #lead> The development of VitePress is guided by an international team, some of whom have chosen to be featured below. </template>
</VPTeamPageTitle>
<VPTeamMembers :members="members" />
</VPTeamPage>
```
创建完整的团队页面时,请记住用 `<VPTeamPage>` 组件包装所有团队相关组件,以获得正确的布局结构,如间距。
`<VPPageTitle>` 组件添加页面标题部分。标题是 `<h1>` 标题。使用 `#title``#lead` 插槽来介绍你的团队。
`<VPMembers>` 和在 doc 页面中使用时一样。它将显示成员列表。
### 添加分段以划分团队成员 {#add-sections-to-divide-team-members}
你可以将“分段”添加到团队页面。例如,你可能有不同类型的团队成员,例如核心团队成员和社区合作伙伴。你可以将这些成员分成几个部分,以更好地解释每组的角色。
为此,将 `<VPTeamPageSection>` 组件添加到我们之前创建的 `team.md` 文件中。
```html
---
layout: page
---
<script setup>
import {
VPTeamPage,
VPTeamPageTitle,
VPTeamMembers,
VPTeamPageSection
} from 'vitepress/theme'
const coreMembers = [...]
const partners = [...]
</script>
<VPTeamPage>
<VPTeamPageTitle>
<template #title>Our Team</template>
<template #lead>...</template>
</VPTeamPageTitle>
<VPTeamMembers size="medium" :members="coreMembers" />
<VPTeamPageSection>
<template #title>Partners</template>
<template #lead>...</template>
<template #members>
<VPTeamMembers size="small" :members="partners" />
</template>
</VPTeamPageSection>
</VPTeamPage>
```
`<VPTeamPageSection>` 组件可以有类似于 `VPTeamPageTitle` 组件的 `#title``#lead` 插槽,还有用于显示团队成员的 `#members` 插槽。
请记住将 `<VPTeamMembers>` 组件放入 `#members` 插槽中。
## `<VPTeamMembers>`
`<VPTeamMembers>` 组件显示给定的成员列表。
```html
<VPTeamMembers
size="medium"
:members="[
{ avatar: '...', name: '...' },
{ avatar: '...', name: '...' },
...
]" />
```
```ts
interface Props {
// Size of each members. Defaults to `medium`.
size?: 'small' | 'medium'
// List of members to display.
members: TeamMember[]
}
interface TeamMember {
// Avatar image for the member.
avatar: string
// Name of the member.
name: string
// Title to be shown below member's name.
// e.g. Developer, Software Engineer, etc.
title?: string
// Organization that the member belongs.
org?: string
// URL for the organization.
orgLink?: string
// Description for the member.
desc?: string
// Social links. e.g. GitHub, Twitter, etc. You may pass in
// the Social Links object here.
// See: https://vitepress.dev/reference/default-theme-config.html#sociallinks
links?: SocialLink[]
// URL for the sponsor page for the member.
sponsor?: string
}
```
## `<VPTeamPage>`
::: details 创建完整团队页面时的根组件。它只接受一个插槽。它将设置所有传入的团队相关组件的样式。
The root component when creating a full team page. It only accepts a single slot. It will style all passed in team related components.
:::
## `<VPTeamPageTitle>`
添加页面的标题。最好在一开始就在 `<VPTeamPage>` 下使用。它接受 `#title``#lead` 插槽。
```html
<VPTeamPage>
<VPTeamPageTitle>
<template #title> Our Team </template>
<template #lead> The development of VitePress is guided by an international team, some of whom have chosen to be featured below. </template>
</VPTeamPageTitle>
</VPTeamPage>
```
## `<VPTeamPageSection>`
在团队页面中创建一个“分段”。它接受 `#title`、`#lead` 和 `#members` 插槽。你可以在 `<VPTeamPage>` 中添加任意数量的分段。
```html
<VPTeamPage>
...
<VPTeamPageSection>
<template #title>Partners</template>
<template #lead>Lorem ipsum...</template>
<template #members>
<VPTeamMembers :members="data" />
</template>
</VPTeamPageSection>
</VPTeamPage>
```
[未出现在侧边栏的完整团队页面](./team)

@ -0,0 +1,169 @@
---
outline: deep
---
# Frontmatter 配置 {#frontmatter-config}
Frontmatter 支持基于页面的配置。在每个 markdown 文件中,你可以使用 frontmatter 配置来覆写站点级别或主题级别的配置选项。此外,还有一些配置选项只能在 frontmatter 中定义。
示例用法:
```md
---
title: Docs with VitePress
editLink: true
---
```
你可以通过 Vue 表达式中的 `$frontmatter` 全局变量访问 frontmatter 数据:
```md
{{ $frontmatter.title }}
```
## 标题 {#title}
- key: `title`
- Type: `string`
Title for the page. It's same as [config.title](./site-config#title), and it overrides the site-level config.
```yaml
---
title: VitePress
---
```
## 标题模板 {#titletemplate}
- key: `titleTemplate`
- Type: `string | boolean`
标题的后缀。它与 [config.titleTemplate](./site-config#titletemplate) 相同,它会覆盖站点级别的配置。
```yaml
---
title: VitePress
titleTemplate: Vite & Vue powered static site generator
---
```
## 描述 {#description}
- key: `description`
- Type: `string`
页面的描述。它与 [config.description](./site-config#description) 相同,它会覆盖站点级别的配置。
```yaml
---
description: VitePress
---
```
## 头部标签 {#head}
- key: `head`
- Type: `HeadConfig[]`
指定要为当前页面注入的额外 head 标签。将附加在站点级配置注入的头部标签之后。
```yaml
---
head:
- - meta
- name: description
content: hello
- - meta
- name: keywords
content: super duper SEO
---
```
```ts
type HeadConfig = [string, Record<string, string>] | [string, Record<string, string>, string]
```
## 仅默认主题 {#default-theme-only}
以下 frontmatter 选项仅在使用默认主题时适用。
### 布局 <Badge type="info" text="default theme only" /> {#layout}
- key: `layout`
- Type: `doc | home | page`
- Default: `doc`
指定页面的布局。
- `doc` - 它将默认文档样式应用于 markdown 内容。
- `home` - “主页”的特殊布局。你可以添加额外的选项,例如 `hero``features`,以快速创建漂亮的落地页。
- `page` - 表现类似于 `doc`,但它不对内容应用任何样式。当你想创建一个完全自定义的页面时很有用。
```yaml
---
layout: doc
---
```
### hero <Badge type="info" text="default theme only" /> <Badge type="info" text="Home page only" />
`layout` 设置为 `home` 时,定义主页 hero 部分的内容。更多详细信息:[默认主题:主页](./default-theme-home-page)。
### features <Badge type="info" text="default theme only" /> <Badge type="info" text="Home page only" />
定义当`layout` 设置为 `home` 时要在 features 部分中显示的项目。更多详细信息:[默认主题:主页](./default-theme-home-page)。
### 大纲开关 <Badge type="info" text="default theme only" /> {#aside}
- key: `aside`
- Type: `boolean | 'left'`
- Default: `true`
定义 aside 组件在 `doc` 布局中的位置。
将此值设置为 `false` 可禁用 aside 容器。\
将此值设置为 `true` 会将 aside 渲染到右侧。\
将此值设置为 `left` 会将 aside 渲染到左侧。
```yaml
---
aside: false
---
```
### 大纲层级 <Badge type="info" text="default theme only" /> {#outline}
- key: `outline`
- Type: `number | [number, number] | 'deep' | false`
- Default: `2`
大纲中显示的标题级别。它与 [config.themeConfig.outline](./default-theme-config#outline) 相同,它会覆盖主题配置。
### 最近更新时间 <Badge type="info" text="default theme only" /> {#lastupdated}
- key: `lastUpdated`
- Type: `boolean`
- Default: `true`
是否在当前页面的页脚中显示[最近更新时间](./default-theme-last-updated)的文本。
```yaml
---
lastUpdated: false
---
```
### 编辑链接 <Badge type="info" text="default theme only" /> {#editlink}
- key: `editLink`
- Type: `boolean`
- Default: `true`
是否在当前页的页脚显示[编辑链接](./default-theme-edit-link)。
```yaml
---
editLink: false
---
```

@ -0,0 +1,147 @@
# 运行时 API {#runtime-api}
VitePress 提供了几个内置的 API 来让你访问应用程序数据。 VitePress 还附带了一些可以在全局范围内使用的内置组件。
辅助函数可从 `vitepress` 全局导入,通常用于自定义主题 Vue 组件。但是,它们也可以在 `.md` 页面内使用,因为 markdown 文件被编译成 Vue [单文件组件](https://vuejs.org/guide/scaling-up/sfc.html)。
`use*` 开头的方法表示它是一个 [Vue 3 Composition API](https://vuejs.org/guide/introduction.html#composition-api) 函数“Composable(可组合)”),只能在 `setup()``<script setup>` 中使用。
## `useData` <Badge type="info" text="composable" />
返回特定页面的数据。返回的对象具有以下类型:
```ts
interface VitePressData<T = any> {
/**
* Site-level metadata
*/
site: Ref<SiteData<T>>
/**
* themeConfig from .vitepress/config.js
*/
theme: Ref<T>
/**
* Page-level metadata
*/
page: Ref<PageData>
/**
* Page frontmatter
*/
frontmatter: Ref<PageData['frontmatter']>
/**
* Dynamic route params
*/
params: Ref<PageData['params']>
title: Ref<string>
description: Ref<string>
lang: Ref<string>
isDark: Ref<boolean>
dir: Ref<string>
localeIndex: Ref<string>
}
interface PageData {
title: string
titleTemplate?: string | boolean
description: string
relativePath: string
headers: Header[]
frontmatter: Record<string, any>
params?: Record<string, any>
isNotFound?: boolean
lastUpdated?: number
}
```
**示例:**
```vue
<script setup>
import { useData } from 'vitepress'
const { theme } = useData()
</script>
<template>
<h1>{{ theme.footer.copyright }}</h1>
</template>
```
## `useRoute` <Badge type="info" text="composable" />
返回具有以下类型的当前路由对象:
```ts
interface Route {
path: string
data: PageData
component: Component | null
}
```
## `useRouter` <Badge type="info" text="composable" />
返回 VitePress 路由实例,以便你可以以编程方式导航到另一个页面。
```ts
interface Router {
route: Route
go: (href?: string) => Promise<void>
}
```
## `withBase` <Badge type="info" text="helper" />
- **Type**: `(path: string) => string`
将配置的 [`base`](./site-config#base) 追加到给定的 URL 路径。另请参阅 [Base URL](../guide/asset-handling#base-url)。
## `<Content />` <Badge type="info" text="component" />
`<Content />` 组件显示渲染的 markdown 内容。在[创建自己的主题时](../guide/custom-theme)很有用。
```vue
<template>
<h1>Custom Layout!</h1>
<Content />
</template>
```
## `<ClientOnly />` <Badge type="info" text="component" />
`<ClientOnly />` 组件仅在客户端渲染其插槽。
由于 VitePress 应用程序在生成静态构建时是在 Node.js 中服务器渲染的,因此任何 Vue 使用都必须符合通用代码要求。简而言之,确保仅在 beforeMount 或 mounted 钩子中访问 Browser/DOM API。
::: details 如果你正在使用或演示对 SSR 不友好的组件(例如,包含自定义指令),你可以将它们包装在 `ClientOnly` 组件中。
If you are using or demoing components that are not SSR-friendly (for example, contain custom directives), you can wrap them inside the `ClientOnly` component.
:::
```vue-html
<ClientOnly>
<NonSSRFriendlyComponent />
</ClientOnly>
```
- 相关文档: [SSR 兼容性](/guide/ssr-compat)
## `$frontmatter` <Badge type="info" text="template global" />
在 Vue 表达式中直接访问当前页面的 [frontmatter](../guide/frontmatter) 数据。
```md
---
title: Hello
---
# {{ $frontmatter.title }}
```
## `$params` <Badge type="info" text="template global" />
在 Vue 表达式中直接访问当前页面的[动态路由参数](../guide/routing#dynamic-routes)。
```md
- package name: {{ $params.pkg }}
- version: {{ $params.version }}
```

@ -0,0 +1,610 @@
---
outline: deep
---
# 站点配置 {#site-config}
Site config 可以定义站点的全局设置。App config 配置选项适用于每个 VitePress 站点,无论它使用什么主题。例如 base 目录或网站的标题。
## 概览 {#overview}
### 配置解析 {#config-resolution}
配置文件总是从 `<root>/.vitepress/config.[ext]` 解析,其中 `<root>` 是你的 VitePress [项目根目录](../guide/routing#root-and-source-directory)`[ext]` 是支持的文件扩展名之一。开箱即用地支持 TypeScript。支持的扩展名包括 `.js`、`.ts`、`.cjs`、`.mjs`、`.cts` 和 `.mts`
建议在配置文件中使用 ES 模块语法。配置文件应该默认导出一个对象:
```ts
export default {
// app level config options
lang: 'en-US',
title: 'VitePress',
description: 'Vite & Vue powered static site generator.',
...
}
```
### 配置智能提示 {#config-intellisense}
使用 `defineConfig` 辅助函数将为配置选项提供 TypeScript 支持的智能提示。假设你的 IDE 支持它,那么智能提示在 JavaScript 和 TypeScript 中都将触发。
```js
import { defineConfig } from 'vitepress'
export default defineConfig({
// ...
})
```
### 主题类型提示 {#typed-theme-config}
默认情况下,`defineConfig` 辅助函数期望默认主题的主题配置数据类型:
```ts
import { defineConfig } from 'vitepress'
export default defineConfig({
themeConfig: {
// Type is `DefaultTheme.Config`
},
})
```
如果你使用自定义主题并希望对主题配置进行类型检查,则需要改用 `defineConfigWithTheme`,并通过通用参数传递自定义主题的配置类型:
```ts
import { defineConfigWithTheme } from 'vitepress'
import type { ThemeConfig } from 'your-theme'
export default defineConfigWithTheme<ThemeConfig>({
themeConfig: {
// Type is `ThemeConfig`
},
})
```
### Vite, Vue & Markdown Config
- **Vite**
你可以使用 VitePress 配置中的 [vite](#vite) 选项配置底层 Vite 实例。无需创建单独的 Vite 配置文件。
- **Vue**
VitePress 已经包含 Vite 的官方 Vue 插件([@vitejs/plugin-vue](https://github.com/vitejs/vite-plugin-vue))。你可以配置 VitePress 中的 [vue](#vue) 选项。
- **Markdown**
你可以使用 VitePress 配置中的 [markdown](#markdown) 选项配置底层的 [Markdown-It](https://github.com/markdown-it/markdown-it) 实例。
## 站点元数据 {#site-metadata}
### 标题 {#title}
- key `title`
- Type: `string`
- Default: `VitePress`
- 每个页面可以通过 [frontmatter](./frontmatter-config#title) 覆写
网站的标题。使用默认主题时,这将显示在导航栏中。
它还将用作所有单独页面标题的默认后缀,除非定义了 [`titleTemplate`](#titletemplate)。单个页面的最终标题将是其第一个 `<h1>` 标题的文本内容加上的全局 `title`。例如使用以下配置和页面内容:
```ts
export default {
title: 'My Awesome Site',
}
```
```md
# Hello
```
页面标题就是 `Hello | My Awesome Site`.
### 标题模板 {#titletemplate}
- key: `titleTemplate`
- Type: `string | boolean`
- 每个页面可以通过 [frontmatter](./frontmatter-config#titletemplate) 覆写
允许自定义每个页面的标题后缀或整个标题。例如:
```ts
export default {
title: 'My Awesome Site',
titleTemplate: 'Custom Suffix',
}
```
```md
# Hello
```
页面标题就是 `Hello | Custom Suffix`.
要完全自定义标题的呈现方式,你可以在 `titleTemplate` 中使用 `:title` 标识符:
```ts
export default {
titleTemplate: ':title - Custom Suffix',
}
```
这里的 `:title` 将替换为从页面的第一个 `<h1>` 标题推断出的文本。上一个示例页面的标题将是 `Hello - Custom Suffix`
该选项可以设置为 `false` 以禁用标题后缀。
### 描述 {#description}
- key: `description`
- Type: `string`
- Default: `A VitePress site`
- 每个页面可以通过 [frontmatter](./frontmatter-config#description) 覆写
网站的描述。这将呈现为页面 HTML 中的 `<meta>` 标签。
```ts
export default {
description: 'A VitePress site',
}
```
### head
- key: `head`
- Type: `HeadConfig[]`
- Default: `[]`
- 每个页面可以通过 [frontmatter](./frontmatter-config#head) 添加
::: details 要在页面 HTML 的 `<head>` 标记中呈现的其他元素。用户添加的标签在结束 `head` 标签之前呈现,在 VitePress 标签之后。
Additional elements to render in the `<head>` tag in the page HTML. The user-added tags are rendered before the closing `head` tag, after VitePress tags.
:::
```ts
export default {
head: [
['link', { rel: 'preconnect', href: 'https://fonts.gstatic.com', crossorigin: '' }],
// would render: <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
],
}
```
```ts
type HeadConfig = [string, Record<string, string>] | [string, Record<string, string>, string]
```
### 语言 {#lang}
- key: `lang`
- Type: `string`
- Default: `en-US`
站点的 lang 属性。这将呈现为页面 HTML 中的 `<html lang="en-US">` 标签。
```ts
export default {
lang: 'en-US',
}
```
### base
- key: `base`
- Type: `string`
- Default: `/`
站点将部署到的 base URL。如果你计划在子路径例如 GitHub 页面)下部署站点,则需要设置此项。如果你计划将你的站点部署到 `https://foo.github.io/bar/`,那么你应该将 `base` 设置为 `“/bar/”`。它应该始终以 `/`开头和结尾。
base 会自动添加到其他选项中以 `/` 开头的所有 URL 前面,因此你只需指定一次。
```ts
export default {
base: '/base/',
}
```
## 路由 {#routing}
### 简洁 URL {#cleanurls}
- key: `cleanUrls`
- Type: `boolean`
- Default: `false`
当设置为 `true`VitePress 将从 URL 中删除 `.html` 后缀。另请参阅[生成简洁的 URL](../guide/routing#generating-clean-url)。
::: warning 需要服务器支持
要启用此功能,可能需要在你的托管平台上进行额外配置。要使其正常工作,你的服务器必须能够在**不重定向的情况下**访问 `/foo` 时提供 `/foo.html`
:::
### 路由重写 {#rewrites}
- key: `rewrites`
- Type: `Record<string, string>`
自定义目录 <-> URL 映射。详细信息请参阅[路由:路由重写](../guide/routing#route-rewrites)。
```ts
export default {
rewrites: {
'source/:page': 'destination/:page',
},
}
```
## Build
### srcDir
- key: `srcDir`
- Type: `string`
- Default: `.`
markdown 页面的目录,相对于项目根目录。另请参阅[根目录和源目录](../guide/routing#root-and-source-directory)。
```ts
export default {
srcDir: './src',
}
```
### srcExclude
- key: `srcExclude`
- Type: `string`
- Default: `undefined`
::: details 用于匹配应作为源内容输出的 markdown 文件的 [全局模式](https://github.com/mrmlnc/fast-glob#pattern-syntax)。
A [glob pattern](https://github.com/mrmlnc/fast-glob#pattern-syntax) for matching markdown files that should be excluded as source content.
:::
```ts
export default {
srcExclude: ['**/README.md', '**/TODO.md'],
}
```
### outDir
- key: `outDir`
- Type: `string`
- Default: `./.vitepress/dist`
项目的构建输出位置,相对于[项目根目录](../guide/routing#root-and-source-directory)。
```ts
export default {
outDir: '../public',
}
```
### cacheDir
- key: `cacheDir`
- Type: `string`
- Default: `./.vitepress/cache`
缓存文件的目录,相对于[项目根目录](../guide/routing#root-and-source-directory)。另请参阅:[vite: cacheDir](https://cn.vitejs.dev/config/shared-options)。
```ts
export default {
cacheDir: './.vitepress/.vite',
}
```
### 忽略死链 {#ignoredeadlinks}
- key: `ignoreDeadLinks`
- Type: `boolean | 'localhostLinks' | (string | RegExp | ((link: string) => boolean))[]`
- Default: `false`
当设置为 `true`VitePress 不会因为死链而导致构建失败。
当设置为 `'localhostLinks'` ,出现死链时构建将失败,但不会检查 `localhost` 链接。
```ts
export default {
ignoreDeadLinks: true,
}
```
它也可以是一组精确的 url 字符串、正则表达式模式或自定义过滤函数。
```ts
export default {
ignoreDeadLinks: [
// ignore exact url "/playground"
'/playground',
// ignore all localhost links
/^https?:\/\/localhost/,
// ignore all links include "/repl/""
/\/repl\//,
// custom function, ignore all links include "ignore"
(url) => {
return url.toLowerCase().includes('ignore')
},
],
}
```
### 多页应用 <Badge type="warning" text="experimental" /> {#mpa}
- key: `mpa`
- Type: `boolean`
- Default: `false`
::: details 设置为 `true` 时,生产应用程序将在 [MPA 模式](../guide/mpa-mode)下构建。MPA 模式默认提供 零 JavaScript 支持,代价是禁用客户端导航,并且需要明确选择加入才能进行交互。
When set to `true`, the production app will be built in [MPA Mode](../guide/mpa-mode). MPA mode ships 0kb JavaScript by default, at the cost of disabling client-side navigation and requires explicit opt-in for interactivity.
:::
## 主题 {#theming}
### 外观 {#appearance}
- key: `appearance`
- Type: `boolean | 'dark'`
- Default: `true`
是否启用深色模式(通过将 `.dark` 类添加到 `<html>` 元素)。
- 如果该选项设置为 `true`,则默认主题将由用户的首选配色方案决定。
- 如果该选项设置为 `dark`,则默认情况下主题将是深色的,除非用户手动切换它。
- 如果该选项设置为 `false`,用户将无法切换主题。
此选项注入一个内联脚本,使用 `vitepress-theme-appearance` key 从本地存储恢复用户设置。这确保在呈现页面之前应用 `.dark` 类以避免闪烁。
### 最近更新时间 {#lastupdated}
- key: `lastUpdated`
- Type: `boolean`
- Default: `false`
是否使用 Git 获取每个页面的最后更新时间戳。时间戳将包含在每个页面的页面数据中,可通过 [`useData`](./runtime-api#usedata) 访问。
使用默认主题时,启用此选项将显示每个页面的最后更新时间。你可以通过 [`themeConfig.lastUpdatedText`](./default-theme-config#lastupdatedtext) 选项自定义文本。
## 定制 {#customization}
### markdown
- key: `markdown`
- Type: `MarkdownOption`
配置 Markdown 解析器选项。 VitePress 使用 [Markdown-it](https://github.com/markdown-it/markdown-it) 作为解析器,使用 [Shiki](https://shiki.matsu.io/) 来高亮不同语言语法。在此选项中,你可以传递各种 Markdown 相关选项以满足你的需要。
```js
export default {
markdown: {
theme: 'material-theme-palenight',
lineNumbers: true,
// adjust how header anchors are generated,
// useful for integrating with tools that use different conventions
anchors: {
slugify(str) {
return encodeURIComponent(str)
},
},
},
}
```
以下是你可以在此对象中可配置的所有选项:
```ts
interface MarkdownOptions extends MarkdownIt.Options {
// Custom theme for syntax highlighting.
// You can use an existing theme.
// See: https://github.com/shikijs/shiki/blob/main/docs/themes.md#all-themes
// Or add your own theme.
// See: https://github.com/shikijs/shiki/blob/main/docs/themes.md#loading-theme
theme?: Shiki.IThemeRegistration | { light: Shiki.IThemeRegistration; dark: Shiki.IThemeRegistration }
// Enable line numbers in code block.
lineNumbers?: boolean
// Add support for your own languages.
// https://github.com/shikijs/shiki/blob/main/docs/languages.md#supporting-your-own-languages-with-shiki
languages?: Shiki.ILanguageRegistration
// markdown-it-anchor plugin options.
// See: https://github.com/valeriangalliat/markdown-it-anchor#usage
anchor?: anchorPlugin.AnchorOptions
// markdown-it-attrs plugin options.
// See: https://github.com/arve0/markdown-it-attrs
attrs?: {
leftDelimiter?: string
rightDelimiter?: string
allowedAttributes?: string[]
disable?: boolean
}
// specify default language for syntax highlighter
defaultHighlightLang?: string
// @mdit-vue/plugin-frontmatter plugin options.
// See: https://github.com/mdit-vue/mdit-vue/tree/main/packages/plugin-frontmatter#options
frontmatter?: FrontmatterPluginOptions
// @mdit-vue/plugin-headers plugin options.
// See: https://github.com/mdit-vue/mdit-vue/tree/main/packages/plugin-headers#options
headers?: HeadersPluginOptions
// @mdit-vue/plugin-sfc plugin options.
// See: https://github.com/mdit-vue/mdit-vue/tree/main/packages/plugin-sfc#options
sfc?: SfcPluginOptions
// @mdit-vue/plugin-toc plugin options.
// See: https://github.com/mdit-vue/mdit-vue/tree/main/packages/plugin-toc#options
toc?: TocPluginOptions
// Configure the Markdown-it instance.
config?: (md: MarkdownIt) => void
}
```
### vite
- key: `vite`
- Type: `import('vite').UserConfig`
将原始 [Vite 配置](https://vitejs.dev/config/)传递给内部 Vite 开发服务器 / bundler。
```js
export default {
vite: {
// Vite config options
},
}
```
### vue
- key: `vue`
- Type: `import('@vitejs/plugin-vue').Options`
将原始的 [@vitejs/plugin-vue 选项](https://github.com/vitejs/vite-plugin-vue/tree/main/packages/plugin-vue#options)传递给内部插件实例。
```js
export default {
vue: {
// @vitejs/plugin-vue options
},
}
```
## 构建钩子 {#build-hooks}
VitePress build hooks allow you to add new functionality and behaviors to your website:
VitePress 构建钩子允许你向你的网站添加新功能和行为:
- Sitemap 网站地图
- Search Indexing 搜索索引
- PWA 渐进式网页应用
- Teleports 传送门
### buildEnd
- key: `buildEnd`
- Type: `(siteConfig: SiteConfig) => Awaitable<void>`
`buildEnd` 是一个构建 CLI 钩子它将在构建SSG完成后但在 VitePress CLI 进程退出之前运行。
```ts
export default {
async buildEnd(siteConfig) {
// ...
},
}
```
### postRender
- key: `postRender`
- Type: `(context: SSGContext) => Awaitable<SSGContext | void>`
::: details `postRender` 是一个构建钩子,在 SSG 渲染完成时调用。它将允许你在 SSG(静态站点生成) 期间处理传递的内容。
`postRender` is a build hook, called when SSG rendering is done. It will allow you to handle the teleports content during SSG.
:::
```ts
export default {
async postRender(context) {
// ...
},
}
```
```ts
interface SSGContext {
content: string
teleports?: Record<string, string>
[key: string]: any
}
```
### transformHead
- key: `transformHead`
- Type: `(context: TransformContext) => Awaitable<HeadConfig[]>`
`transformHead` 是一个构建钩子,用于在生成每个页面之前转换 head。它将允许你添加无法静态添加到你的 VitePress 配置中的 head entries。你只需要返回额外的 entries它们将自动与现有 entries 合并。
::: warning 警告
不要改变 `ctx` 中的任何东西。
:::
```ts
export default {
async transformHead(context) {
// ...
},
}
```
```ts
interface TransformContext {
page: string // e.g. index.md (relative to srcDir)
assets: string[] // all non-js/css assets as fully resolved public URL
siteConfig: SiteConfig
siteData: SiteData
pageData: PageData
title: string
description: string
head: HeadConfig[]
content: string
}
```
### transformHtml
- key: `transformHtml`
- Type: `(code: string, id: string, ctx: TransformContext) => Awaitable<string | void>`
`transformHtml` 是一个构建钩子,用于在保存到磁盘之前转换每个页面的内容。
::: warning 警告
不要改变 `ctx` 中的任何东西。另外,修改 html 内容可能会导致运行时出现 hydration 问题。
:::
```ts
export default {
async transformHtml(code, id, context) {
// ...
},
}
```
### transformPageData
- key: `transformPageData`
- Type: `(pageData: PageData, ctx: TransformPageContext) => Awaitable<Partial<PageData> | { [key: string]: any } | void>`
`transformPageData` 是一个钩子,用于转换每个页面的 `pageData`。你可以直接改变 `pageData` 或返回将合并到 `PageData` 中的更改值。
::: warning 警告
不要改变 `ctx` 中的任何东西。
:::
```ts
export default {
async transformPageData(pageData, { siteConfig }) {
pageData.contributors = await getPageContributors(pageData.relativePath)
}
// or return data to be merged
async transformPageData(pageData, { siteConfig }) {
return {
contributors: await getPageContributors(pageData.relativePath)
}
}
}
```
```ts
interface TransformPageContext {
siteConfig: SiteConfig
}
```

@ -0,0 +1,80 @@
---
layout: page
---
<script setup>
import {
VPTeamPage,
VPTeamPageTitle,
VPTeamMembers,
VPTeamPageSection
} from 'vitepress/theme'
const coreMembers = [
{
avatar: 'https://www.github.com/yyx990803.png',
name: 'Evan You',
title: 'Creator',
links: [
{ icon: 'github', link: 'https://github.com/yyx990803' },
{ icon: 'twitter', link: 'https://twitter.com/youyuxi' }
]
},
{
avatar: 'https://www.github.com/yyx990803.png',
name: 'Evan You',
title: 'Creator',
links: [
{ icon: 'github', link: 'https://github.com/yyx990803' },
{ icon: 'twitter', link: 'https://twitter.com/youyuxi' }
]
},
{
avatar: 'https://www.github.com/yyx990803.png',
name: 'Evan You',
title: 'Creator',
links: [
{ icon: 'github', link: 'https://github.com/yyx990803' },
{ icon: 'twitter', link: 'https://twitter.com/youyuxi' }
]
},
]
const partners = [
{
avatar: 'https://avatars.githubusercontent.com/u/50388827?v=4',
name: 'VanchKong',
title: 'Translator',
links: [
{ icon: 'github', link: 'https://github.com/vanchKong' },
]
},
]
</script>
<VPTeamPage>
<VPTeamPageTitle>
<template #title>Our Team</template>
<!-- <template #lead>...</template> -->
</VPTeamPageTitle>
<VPTeamPageSection>
<template #title>核心成员</template>
<template #members>
<VPTeamMembers size="medium" :members="coreMembers" />
</template>
</VPTeamPageSection>
<VPTeamPageSection>
<template #title>合作伙伴</template>
<!-- <template #lead>...</template> -->
<template #members>
<VPTeamMembers size="small" :members="partners" />
</template>
</VPTeamPageSection>
</VPTeamPage>
<!-- <p class="red">123</p>
<style>
.red {
color: red;
}
</style> -->
Loading…
Cancel
Save