跳轉到內容

路由 ​

基於文件的路由 ​

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 服务器上。

根目录和源目录 ​

VitePress 项目的文件结构中有两个重要的概念:项目根目录 (project root) 和源目录 (source directory)。

项目根目录 ​

项目根目录是 VitePress 将尝试寻找 .vitepress 特殊目录的地方。.vitepress 目录是 VitePress 配置文件、開發服务器缓存、构建输出和可选主題自訂程式碼的预留位置。

当从命令行运行 vitepress dev 或 vitepress build 时,VitePress 将使用目前工作目录作为项目根目录。要将子目录指定为根目录,需要将相对路径传递给命令。例如,如果 VitePress 项目位于 ./docs,应该运行 vitepress dev docs:

.
├─ docs                    # 项目根目录
│  ├─ .vitepress           # 配置目录
│  ├─ getting-started.md
│  └─ index.md
└─ ...
sh
vitepress dev docs

这将导致以下源程式碼到 HTML 的映射:

docs/index.md            -->  /index.html (可以通過 / 访问)
docs/getting-started.md  -->  /getting-started.html

源目录 ​

源目录是 Markdown 源文件所在的位置。默认情况下,它與项目根目录相同。但是,可以通過 srcDir 配置选项对其进行配置。

srcDir 选项是相对于项目根目录解析的。例如,对于 srcDir: 'src',文件结构将如下所示:

.                          # 项目根目录
├─ .vitepress              # 配置目录
└─ src                     # 源目录
   ├─ getting-started.md
   └─ index.md

生成的源程式碼到 HTML 的映射:

src/index.md            -->  /index.html (可以通過 / 访问)
src/getting-started.md  -->  /getting-started.html

連結頁面 ​

在頁面之间連結时,可以使用绝对路径和相对路径。请注意,虽然 .md 和 .html 扩展名都可以使用,但最佳做法是省略文件扩展名,以便 VitePress 可以根据配置生成最终的 URL。

md
<!-- Do -->
[Getting Started](./getting-started)
[Getting Started](../guide/getting-started)

<!-- Don't -->
[Getting Started](./getting-started.md)
[Getting Started](./getting-started.html)

在资源處理中了解有关連結到资源(例如圖像)的更多信息。

連結到非 VitePress 頁面 ​

如果想連結到站點中不是由 VitePress 生成的頁面,需要使用完整的 URL(在新选项卡中開啟)或明确指定 target:

输入

md
[Link to pure.html](/pure.html){target="_self"}

输出

Link to pure.html

注意

在 Markdown 連結中,base 會自动新增到 URL 前面。这意味着,如果想連結到 base 之外的頁面,则連結中需要類似 ../../pure.html 的内容(由浏览器相对于目前頁面解析)。

或者,可以直接使用锚标记语法:

md
<a href="/pure.html" target="_self">Link to pure.html</a>

生成简洁的 URL ​

需要服务器支援

要使 VitePress 提供简洁 URL,需要服务器端支援。

默认情况下,VitePress 将入站連結解析为以 .html 结尾的 URL。但是,一些用户可能更喜欢没有 .html 扩展名的“简洁 URL”——例如,example.com/path 而不是 example.com/path.html。

某些服务器或托管平台 (例如 Netlify、Vercel 或 GitHub Pages) 提供将 /foo 之类的 URL 映射到 /foo.html (如果存在) 的功能,而无需重定向:

如果可以使用此功能,还可以啟用 VitePress 自己的 cleanUrls 配置选项,以便:

  • 頁面之间的入站連結是在没有 .html 扩展名的情况下生成的。
  • 如果目前路径以 .html 结尾,路由器将执行客戶端重定向到无扩展路径。

但是,如果無法为服务器配置此类支援,则必须手动采用以下目录结构:

.
├─ getting-started
│  └─ index.md
├─ installation
│  └─ index.md
└─ index.md

路由重写 ​

可以自訂源目录结构和生成頁面之间的映射。当有一个复杂的项目结构时,它很有用。例如,假设有一个包含多个包的 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 选项来实现此目的:

.vitepress/config.js
ts
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 包编译的——请参阅其文件以获取更多语法。

開啟重写功能时使用相对連結

啟用重写後,相对連結应基於重写的路径。例如,为了建立从 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)

动態路由 ​

可以使用单个 Markdown 文件和动態数据生成许多頁面。例如,可以建立一个 packages/[pkg].md 文件,为项目中的每个包生成相应的頁面。这里,[pkg] 段是一个路由参数,用于区分每个頁面。

路径加载文件 ​

由于 VitePress 是靜態站點生成器,因此必须在构建时确定可能的頁面路径。因此,动態路由頁面必须伴随路径加载文件。对于 packages/[pkg].md,我们需要 packages/[pkg].paths.js (也支援 .ts):

.
└─ packages
   ├─ [pkg].md         # 路由模板
   └─ [pkg].paths.js   # 路由路径加载器

路径加载器应该提供一个带有 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

多参数 ​

动態路由可以包含多个参数:

文件结构

.
└─ 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

动態生成路径 ​

路径加载器模块在 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
        }
      }
    })
  }
}

访问頁面中的参数 ​

可以使用参数将附加数据传递到每个頁面。Markdown 路由文件可以通過 $params 全局属性访问 Vue 表达式中的目前頁面参数:

md
- package name: {{ $params.pkg }}
- version: {{ $params.version }}

还可以通過 useData 執行階段 API 访问目前頁面的参数。这在 Markdown 文件和 Vue 组件中都可用:

vue
<script setup>
import { useData } from 'vitepress'

// params 是一个 Vue ref
const { params } = useData()

console.log(params.value)
</script>

渲染原始内容 ​

传递给頁面的参数将在客戶端 JavaScript payload 中序列化,因此应该避免在参数中传递大量数据,例如从远程 CMS 获取的原始 Markdown 或 HTML 内容。

相反,可以使用每个路径对象上的 content 属性将此类内容传递到每个頁面:

js
export default {
  async paths() {
    const posts = await (await fetch('https://my-cms.com/blog-posts')).json()

    return posts.map((post) => {
      return {
        params: { id: post.id },
        content: post.content // 原始 Markdown 或 HTML
      }
    })
  }
}

然後,使用以下特殊语法将内容呈现为 Markdown 文件本身的一部分:

md
<!-- @content -->

最後更新於:

基於 MIT 授權發布