VitePress学习-自定义主题

VitePress-自定义主题

代码仓库

基础了解

初始化项目的时候选择 custom theme

运行后会发现页面挺丑的。

如果想要用默认主题怎么办呢,修改Layout。

使用默认主题的Layout

html 复制代码
<script setup lang="ts">
import { useData } from 'vitepress';
import DefaultTheme from 'vitepress/theme';
// https://vitepress.dev/reference/runtime-api#usedata
const { site, frontmatter } = useData();
const { Layout } = DefaultTheme;
</script>

<template>
  <Layout> <Content /></Layout>
  <!-- <div v-if="frontmatter.home">
    <h1>{{ site.title }}</h1>
    <p>{{ site.description }}</p>
    <ul>
      <li><a href="/markdown-examples.html">Markdown Examples</a></li>
      <li><a href="/api-examples.html">API Examples</a></li>
    </ul>
  </div>
  <div v-else>
    <a href="/">Home</a>
    <Content />
  </div> -->
</template>

你可以在这个目录下找到他的默认组件

components里面可以侧重关注,因为自定义组件的话,大部分都是改这里的东西。

看下刚刚改的效果。

在配置项里面加nav和sidebar

ts 复制代码
import { defineConfig } from 'vitepress';

// https://vitepress.dev/reference/site-config
export default defineConfig({
  title: '我的博客',
  description: '我的博客',
  themeConfig: {
    nav: [
      { text: 'Home', link: '/' },
      { text: 'Examples', link: '/markdown-examples' },
    ],

    sidebar: [
      {
        text: 'Examples',
        items: [
          { text: 'Markdown Examples', link: '/markdown-examples' },
          { text: 'Runtime API Examples', link: '/api-examples' },
        ],
      },
    ],
  },
});

其实就是使用了官方的组件,自定义的话,就是自己写样式,写组件。

回到开始,不使用官方的。

思考,既然都是vue组件,可不可以用element-plus呢,来试一试。

sh 复制代码
npm install element-plus --save

开始

我让豆包帮我生成了一个图,来当作首页吧

首先布局

顶部Header,下面是列表。

先来编写组件。

组件Header

需要了解一个方法useData
useData

在config.mts中配置logo方便我们调试。

在theme下新建一个theme/component/Header.vue文件

首先我看来看看官方是怎么实现header的,在node_modules里面找到VPNav

复制出来,放到我们自己的Header组件中。

然后修改下引用路径

html 复制代码
<script setup lang="ts">
import { inBrowser } from 'vitepress';
import { computed, provide, watchEffect } from 'vue';

import { useData } from 'vitepress';
import { useNav } from 'vitepress/dist/client/theme-default/composables/nav';
import VPNavBar from 'vitepress/dist/client/theme-default/components/VPNavBar.vue';
import VPNavScreen from 'vitepress/dist/client/theme-default/components/VPNavScreen.vue';

const { isScreenOpen, closeScreen, toggleScreen } = useNav();
const { frontmatter } = useData();

const hasNavbar = computed(() => {
  return frontmatter.value.navbar !== false;
});

provide('close-screen', closeScreen);

watchEffect(() => {
  if (inBrowser) {
    document.documentElement.classList.toggle('hide-nav', !hasNavbar.value);
  }
});
</script>

<template>
  <header v-if="hasNavbar" class="VPNav">
    <VPNavBar :is-screen-open="isScreenOpen" @toggle-screen="toggleScreen">
      <template #nav-bar-title-before
        ><slot name="nav-bar-title-before"
      /></template>
      <template #nav-bar-title-after
        ><slot name="nav-bar-title-after"
      /></template>
      <template #nav-bar-content-before
        ><slot name="nav-bar-content-before"
      /></template>
      <template #nav-bar-content-after
        ><slot name="nav-bar-content-after"
      /></template>
    </VPNavBar>
    <VPNavScreen :open="isScreenOpen">
      <template #nav-screen-content-before
        ><slot name="nav-screen-content-before"
      /></template>
      <template #nav-screen-content-after
        ><slot name="nav-screen-content-after"
      /></template>
    </VPNavScreen>
  </header>
</template>

<style scoped>
.VPNav {
  position: relative;
  top: var(--vp-layout-top-height, 0px);
  /*rtl:ignore*/
  left: 0;
  z-index: var(--vp-z-index-nav);
  width: 100%;
  pointer-events: none;
  transition: background-color 0.5s;
}

@media (min-width: 960px) {
  .VPNav {
    position: fixed;
  }
}
</style>

在Layout里面引入下Header。

这里的Main你可以先创建下。

html 复制代码
<script setup lang="ts">
import { useData } from 'vitepress';
import DefaultTheme from 'vitepress/theme';
import Header from './components/Header.vue';
import Main from './components/Main.vue';
import Home from './components/Home.vue';

// https://vitepress.dev/reference/runtime-api#usedata
const data = useData();
console.log(data);
const theme = data.theme;
const { Layout } = DefaultTheme;
</script>

<template>
  <!-- <layout /> -->
  <el-container>
    <Header />
    <Main>
      <Content />
    </Main>
  </el-container>
</template>

看效果

在config.mts中开启检索。

如果不想大改,可以在官方组件基础上改。

站点元数据可以通过useData来获取,组件中引入使用。

在改造主题的时候,避免使用固定设置,尽量和原组件保持一致,使用站点元数据,这样自定义的主题可以让别人也使用。

其他组件

目录结构大哥就这样。

其实就是自己写一套Layout 布局,然后渲染还是借助vitepress,实际上vitepress使用的是markdown-it来渲染的。

NavBar也是copy的官方组件源码修改的。调整了下组件顺序已经隐藏标题。

Home组件的话,可以在Layout里面写

也可以使用文档-重写组件

除此之外,你也可以自定义主题色,具体变量看这个文件
https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css

同样可以动态设置css来实现动态样式。

自定义的样式文件记得引入到.vitepress/theme/index.js