继承

VuePress 默认主题有着大量的用户,因此我们对它进行了一些便于继承的设计,以便用户轻松进行定制化。

VuePress 提供了继承主题的基础能力,但不同的主题可能会提供不同的可继承的功能。因此,如果你使用的是一个社区主题的话,你最好参考主题本身的文档来了解如何继承它。

布局插槽

默认主题的 Layout 布局提供了一些插槽:

  • navbar
  • navbar-before
  • navbar-after
  • sidebar
  • sidebar-top
  • sidebar-bottom
  • page
  • page-top
  • page-bottom

在它们的帮助下,你可以很容易地添加或替换内容。下面通过一个示例来介绍一下如何使用布局插槽来继承默认主题。

首先,创建你的本地主题 .vuepress/theme/index.ts

  1. import type { Theme } from '@vuepress/core'
  2. import { defaultTheme } from '@vuepress/theme-default'
  3. import type { DefaultThemeOptions } from '@vuepress/theme-default'
  4. import { path } from '@vuepress/utils'
  5. export const localTheme = (options: DefaultThemeOptions): Theme => {
  6. return {
  7. name: 'vuepress-theme-local',
  8. extends: defaultTheme(options),
  9. layouts: {
  10. Layout: path.resolve(__dirname, 'layouts/Layout.vue'),
  11. },
  12. }
  13. }

这样你的本地主题将会继承默认主题,并且覆盖 Layout 布局。

接下来,创建 .vuepress/theme/layouts/Layout.vue ,并使用由默认主题的 Layout 布局提供的插槽:

  1. <script setup>
  2. import ParentLayout from '@vuepress/theme-default/lib/client/layouts/Layout.vue'
  3. </script>
  4. <template>
  5. <ParentLayout>
  6. <template #page-bottom>
  7. <div class="my-footer">This is my custom page footer</div>
  8. </template>
  9. </ParentLayout>
  10. </template>
  11. <style lang="css">
  12. .my-footer {
  13. text-align: center;
  14. }
  15. </style>

最后,记得在配置文件中使用你的本地主题:

  1. import { path } from '@vuepress/utils'
  2. import { defineUserConfig } from 'vuepress'
  3. import { localTheme } from './theme'
  4. export default defineUserConfig({
  5. theme: localTheme({
  6. // 默认主题配置项
  7. }),
  8. })

你将会在除了首页外的所有页面添加一个自定义的页脚:

extending-a-theme

组件替换

布局插槽十分实用,但有时候你可能会觉得它不够灵活。默认主题同样提供了替换单个组件的能力。

默认主题将所有 非全局的组件 都注册了一个带 @theme 前缀的 alias 。例如,HomeFooter.vue 的别名是 @theme/HomeFooter.vue

接下来,如果你想要替换 HomeFooter.vue 组件,只需要覆盖这个别名即可:

  1. import type { Theme } from '@vuepress/core'
  2. import { defaultTheme } from '@vuepress/theme-default'
  3. import type { DefaultThemeOptions } from '@vuepress/theme-default'
  4. import { path } from '@vuepress/utils'
  5. export const localTheme = (options: DefaultThemeOptions): Theme => {
  6. return {
  7. name: 'vuepress-theme-local',
  8. extends: defaultTheme(options),
  9. alias: {
  10. '@theme/HomeFooter.vue': path.resolve(__dirname, './components/MyHomeFooter.vue'),
  11. },
  12. }
  13. }

实际上,你不需要继承默认主题就可以进行组件替换。上面提到的 alias 配置项是 插件 API 的一部分,因此你只需要在你的配置文件中设置别名就可以替换组件了:

  1. import { path } from '@vuepress/utils'
  2. import { defaultTheme, defineUserConfig } from 'vuepress'
  3. export default defineUserConfig({
  4. theme: defaultTheme(),
  5. alias: {
  6. '@theme/HomeFooter.vue': path.resolve(__dirname, './components/MyHomeFooter.vue'),
  7. },
  8. })