Skip to content

VitePress 自定义主题

虽然 VitePress 的默认主题功能强大且可配置,但有时你可能需要一个完全独特的设计。VitePress 允许你通过创建一个自定义主题来完全接管站点的 UI。

主题的入口

要使用自定义主题,你需要在 .vitepress 目录下创建一个 theme 目录,并在其中添加一个 index.jsindex.ts 文件。这个文件是你的自定义主题的入口。

.vitepress
└── theme
    └── index.js

一个最基础的自定义主题配置文件如下:

javascript
// .vitepress/theme/index.js
import DefaultTheme from 'vitepress/theme'

export default {
  // 继承默认主题,如果你只想在默认主题基础上进行扩展
  ...DefaultTheme,

  // Layout 是必需的,它将用作每个页面的根组件
  Layout: () => {
    // ... 在这里返回你的自定义布局组件
  }
}

布局组件 (Layout)

Layout 组件是自定义主题的核心。它是一个 Vue 组件,负责渲染页面的整体结构,包括页头、页脚、侧边栏以及最重要的——Markdown 内容。

  1. 创建布局文件

    theme 目录下创建一个 Vue 组件,例如 MyLayout.vue

    .vitepress
    └── theme
        ├── index.js
        └── MyLayout.vue
  2. 编写布局组件

    VitePress 提供了一个特殊的 <Content /> 组件,你必须在你的布局中包含它,它会负责渲染当前页面的 Markdown 内容。

    vue
    <!-- .vitepress/theme/MyLayout.vue -->
    <template>
      <div>
        <header>
          <h1>我的自定义网站</h1>
        </header>
        <main>
          <Content />
        </main>
        <footer>
          <p>版权所有 © 2023</p>
        </footer>
      </div>
    </template>
  3. 在主题中注册布局

    现在,在 index.js 中导入并使用你的布局组件。

    javascript
    // .vitepress/theme/index.js
    import DefaultTheme from 'vitepress/theme'
    import MyLayout from './MyLayout.vue'
    
    export default {
      ...DefaultTheme, // 继承默认主题的样式和一些底层逻辑
      Layout: MyLayout
    }

访问页面数据

在你的自定义布局或任何自定义组件中,你可能需要访问当前页面的数据,例如 frontmatter、标题、路径等。VitePress 提供了 useData 这个 composable 函数来实现这一点。

vue
<!-- .vitepress/theme/MyLayout.vue -->
<script setup>
import { useData } from 'vitepress'

const { page, frontmatter } = useData()
</script>

<template>
  <div>
    <h1>{{ frontmatter.title }}</h1>
    <p>{{ frontmatter.description }}</p>
    <Content />
  </div>
</template>

添加样式

你可以通过多种方式为你的自定义主题添加样式:

  1. 在布局组件中: 直接在 .vue 文件中使用 <style> 标签。

  2. 导入 CSS 文件: 在你的 theme/index.js 中直接导入一个 CSS 文件。

    javascript
    // .vitepress/theme/index.js
    import DefaultTheme from 'vitepress/theme'
    import MyLayout from './MyLayout.vue'
    import './custom.css' // 导入自定义样式
    
    export default {
      Layout: MyLayout,
      // ...
    }

创建自定义主题提供了极高的自由度,但也意味着你需要自己处理更多的细节,如导航、响应式布局等。对于大多数只想做些许调整的用户来说,扩展默认主题(下一章内容)可能是一个更简单高效的选择。