跳到內容

使用自訂佈景主題

佈景主題解析

你可以透過建立一個 .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 偵測到佈景主題入口檔時,它將永遠使用自訂佈景主題,而不是預設佈景主題。不過,你可以 延伸預設佈景主題,對其進行進階自訂化。

佈景主題介面

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 相容

建立版面

最基本的版面元件需要包含一個 <Content /> 元件

vue
<!-- .vitepress/theme/Layout.vue -->
<template>
  <h1>Custom Layout!</h1>

  <!-- this is where markdown content will be rendered -->
  <Content />
</template>

上述版面僅將每個頁面的標記語言作為 HTML 呈現。我們可以新增的第一個改進是處理 404 錯誤

vue
<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() 輔助函式提供我們所有需要用來有條件呈現不同版面的執行時間資料。我們可以存取的其他資料之一是目前頁面的前置資料。我們可以利用這一點,讓最終使用者在每個頁面控制版面。例如,使用者可以使用以下方式指出頁面應使用特殊首頁版面

md
---
layout: home
---

我們可以調整我們的佈景主題來處理這個問題

vue
<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
<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 參考,以取得佈景主題元件中所有可用的資訊。此外,你可以利用 建置時期資料載入 來產生資料驅動的佈局,例如:列出目前專案中所有部落格文章的頁面。

散佈自訂佈景主題

散佈自訂佈景主題最簡單的方式,是將其提供為 GitHub 上的範本儲存庫

如果你想將佈景主題散佈為 npm 套件,請執行下列步驟

  1. 在你的套件進入點中,將佈景主題物件匯出為預設匯出。

  2. 如果適用,請將你的佈景主題組態類型定義匯出為 ThemeConfig

  3. 如果你的佈景主題需要調整 VitePress 組態,請在套件子路徑下 (例如:my-theme/config) 匯出該組態,以便使用者可以延伸它。

  4. 記錄佈景主題組態選項 (透過組態檔案和 frontmatter)。

  5. 提供如何使用你的佈景主題的明確說明 (請見下方)。

使用自訂佈景主題

若要使用外部佈景主題,請從自訂佈景主題進入點匯入並重新匯出它

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/config.ts
import baseConfig from 'awesome-vitepress-theme/config'

export default {
  // extend theme base config (if needed)
  extends: baseConfig
}

最後,如果佈景主題提供其佈景主題組態的類型

ts
// .vitepress/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`
  }
})

在 MIT 授權條款下釋出。