Skip to content

路由详解

了解 VitePress 的路由系统,更好地组织文档结构。

路由基础

VitePress 使用基于文件的路由系统,每个 Markdown 文件对应一个路由。

文件到路由映射

文件路径URL
docs/index.md/
docs/guide.md/guide
docs/guide/index.md/guide/
docs/guide/getting-started.md/guide/getting-started

cleanUrls 配置

ts
export default defineConfig({
  cleanUrls: true  // 移除 .html 后缀
})

启用后:

  • /guide.html/guide
  • /guide//guide

动态路由

动态参数

使用 [param] 语法定义动态路由:

docs/
├── posts/
│   ├── [id].md         # /posts/1, /posts/2, ...
│   └── index.md        # /posts/
└── users/
    └── [user].md       # /users/张三, /users/李四

访问路由参数

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

const { page } = useData()
// page.value.params.id
</script>

<template>
  <h1>文章 ID: {{ page.params.id }}</h1>
</template>

动态路由 Frontmatter

markdown
---
path: /posts/:id(\\d+)
---

# 文章详情

文章 ID: {{ $params.id }}

路由配置

基础路径

部署到子目录时配置:

ts
export default defineConfig({
  base: '/docs/'  // 所有路由前添加前缀
})

结果:

  • /guide/docs/guide
  • /api/config/docs/api/config

路由重写

使用 Frontmatter 自定义路由:

markdown
---
permalink: /custom-path
---

# 页面内容

或使用模式:

markdown
---
permalink: /blog/:year/:month/:day/:slug
---

# 博客文章

路由元数据

访问当前路由

vue
<script setup>
import { useRoute, useRouter } from 'vitepress'

const route = useRoute()
const router = useRouter()
</script>

<template>
  <p>当前路径: {{ route.path }}</p>
  <button @click="router.go('/')">返回首页</button>
</template>

路由对象属性

ts
interface Route {
  path: string           // 当前路径
  data: PageData         // 页面数据
  component: Component   // 页面组件
  params: object         // 路由参数
}

导航

编程式导航

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

const router = useRouter()

function navigate() {
  router.go('/guide/getting-started')
}

function goBack() {
  router.go(-1)  // 返回上一页
}
</script>

声明式导航

markdown
<!-- 内部链接 -->
[指南](/guide/)

<!-- 外部链接 -->
[GitHub](https://github.com)

导航守卫

ts
// docs/.vitepress/theme/index.ts
import DefaultTheme from 'vitepress/theme'

export default {
  extends: DefaultTheme,
  setup() {
    const router = useRouter()
    
    router.onBeforeRouteChange = (to) => {
      // 导航前执行
      console.log('导航到:', to)
    }
    
    router.onAfterRouteChanged = (to) => {
      // 导航后执行
      console.log('已导航到:', to)
    }
  }
}

404 页面

自定义 404 页面

创建 docs/404.md

markdown
---
layout: page
---

# 页面未找到

抱歉,您访问的页面不存在。

[返回首页](/)

动态 404 内容

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

const { site } = useData()
</script>

<template>
  <div class="not-found">
    <h1>404</h1>
    <p>页面未找到</p>
    <a :href="site.base">返回首页</a>
  </div>
</template>

路由钩子

可用钩子

ts
// 导航开始前
router.onBeforeRouteChange = (to: string) => {
  // 返回 false 可取消导航
}

// 页面加载前
router.onBeforePageLoad = (to: string) => {
  // 可以显示加载动画
}

// 页面加载完成
router.onAfterPageLoad = (to: string) => {
  // 隐藏加载动画
  // 执行页面初始化
}

// 路由改变后
router.onAfterRouteChanged = (to: string) => {
  // 发送统计事件
}

完整示例

ts
// docs/.vitepress/theme/index.ts
import DefaultTheme from 'vitepress/theme'
import { useRouter } from 'vitepress'
import { onMounted } from 'vue'

export default {
  extends: DefaultTheme,
  setup() {
    const router = useRouter()

    onMounted(() => {
      router.onBeforeRouteChange = (to) => {
        console.log(`正在导航到: ${to}`)
      }
      
      router.onAfterRouteChanged = (to) => {
        // 更新页面标题
        document.title = document.querySelector('h1')?.textContent || ''
        
        // 发送页面浏览统计
        // trackPageView(to)
      })
    })
  }
}

路由最佳实践

组织文件结构

docs/
├── guide/           # /guide/
│   ├── index.md     # /guide/ (列表页)
│   ├── intro.md     # /guide/intro
│   └── advanced/    # /guide/advanced/
│       └── index.md
├── api/             # /api/
│   └── index.md
└── index.md         # /

URL 设计建议

  1. 使用有意义的路径/guide/getting-started 而非 /gs
  2. 保持层次清晰:使用子目录组织相关内容
  3. 统一命名风格:使用小写和连字符
  4. 避免过深嵌套:建议不超过 3 层

链接规范

markdown
<!-- 推荐:使用尾部斜杠 -->
[指南](/guide/)

<!-- 也可以:不使用尾部斜杠 -->
[指南](/guide)

<!-- 避免:混用 .html -->
[指南](/guide.html)

下一步

学习 组件使用 来创建交互式内容。

贡献者

加载中...

想要成为贡献者?

在 CNB 上参与贡献