VitePress v1.x 动态配置侧边栏

938 阅读4分钟

VitePress 动态配置侧边栏

阿lin这段时间想写个博客,之前VitePress正式推出1.0的时候阿lin就关注了,于是选择了VitePress,本文解释vitepress及配置的信息,没看到有谁写过新版本VitePress动态侧边栏,于是有了这篇文章...

VitePress是什么?

官网: vitepress.dev/
借用官网的话:
VitePress 是一个静态站点生成器 (SSG),专为构建快速、以内容为中心的网站而设计。简而言之,VitePress 获取用 Markdown 编写的源内容,为其应用主题,并生成可以轻松部署在任何地方的静态 HTML 页面。 那么我们开始吧...

安装VitePress

npm add -D vitepress
npx vitepress init
然后就一些配置

image.png

启动项目就可以看到

image.png

基础配置我直接加速✈
  • 搞点图片

image.png

  • 然后配置一下根目录下的index.md
---
# https://vitepress.dev/reference/default-theme-home-page
layout: home

hero:
    name: "Lineo Blog"
    text: "🛫"
    tagline: Happy every day
    image:
        src: /logo.webp
        alt: 开心每一天
    actions:
        - theme: brand
          text: 文档
          link: /markdown-examples
        - theme: alt
          text: API
          link: /api-examples

features:
    - title: HTML
      icon:
          src: /html.svg
      details: HTML(超文本标记语言——HyperText Markup Language)是构成 Web 世界的一砖一瓦。
    - title: CSS
      icon:
          src: /css.svg
      details: CSS 是用来指定文档如何展示给用户的一门语言——如网页的样式、布局、等等。
    - title: JavaScript
      icon:
          src: /javascript.svg
      details: JavaScript 是一门跨平台、面向对象的脚本语言,它能使网页可交互(例如拥有复杂的动画,可点击的按钮,通俗的菜单等)。
    - title: Vue
      icon:
          src: /vue.svg
      details: 它基于标准 HTML、CSS  JavaScript 构建,并提供了一套声明式的、组件化的编程模型,帮助你高效地开发用户界面。
      link: https://cn.vuejs.org/
      linkText: 查看详情
    - title: React
      icon:
          src: /react.svg
      details: 用于构建 Web 和原生交互界面的库
      link: https://zh-hans.react.dev/
      linkText: 查看详情
    - title: nodejs
      icon:
          src: /nodejs.svg
      details: Node.js 是一个开源的、跨平台的 JavaScript 运行时环境。
      link: https://zh-hans.react.dev/
      linkText: 查看详情
---

 <style>
    :root {
      --vp-home-hero-name-color: transparent;
      --vp-home-hero-name-background: -webkit-linear-gradient(120deg, #bd34fe 30%, #41d1ff);

      --vp-home-hero-image-background-image: linear-gradient(-45deg, #bd34fe 50%, #47caff 50%);
      --vp-home-hero-image-filter: blur(44px);
    }

    @media (min-width: 640px) {
      :root {
        --vp-home-hero-image-filter: blur(56px);
      }
    }

    @media (min-width: 960px) {
      :root {
        --vp-home-hero-image-filter: blur(68px);
      }
    }
    </style>

然后页面效果如下

image.png

  • 接着就到 .vitepress/config.mts 我们的重点来了

我们稍微修改一下 配置

import { defineConfig } from "vitepress";

// https://vitepress.dev/reference/site-config
export default defineConfig({
    title: "My Awesome Project",
    description: "A VitePress Site",
    themeConfig: {
        // https://vitepress.dev/reference/default-theme-config
        nav: [
            { text: "Home", link: "/" },
            { text: "Examples", link: "/markdown-examples" },
            { text: "html", link: "/html/index.md" },
            {
                text: "vue",
                items: [
                    {
                        text: "vue2",
                        link: "/vue/vue2/index.md",
                    },
                    {
                        text: "vue3",
                        link: "/vue/vue3/index.md",
                    },
                ],
            },
        ],

        sidebar: [
            {
                text: "Examples",
                items: [
                    { text: "Markdown Examples", link: "/markdown-examples" },
                    { text: "Runtime API Examples", link: "/api-examples" },
                    { text: "vue", link: "/vue" },
                ],
            },
        ],

        socialLinks: [{ icon: "github", link: "https://github.com/vuejs/vitepress" }],
    },
});

对应的是

image.png

我们的重点侧边栏,想想看我只想点击vue的时候出现vue的内容其他不要出现于是我可以配置

sidebar: {
            "/": [
                {
                    text: "VitePress",
                    items: [
                        { text: "Markdown Examples", link: "/markdown-examples" },
                        { text: "Runtime API Examples", link: "/api-examples" },
                    ],
                },
            ],
            "/vue/": [
                {
                    text: "vue",
                    items: [
                        { text: "vue2第一章", link: "/vue/vue2/vue2第一章.md" },
                        { text: "vue3第二章", link: "/vue/vue3/vue3第一章.md" },
                    ],
                },
            ],
        },

然后我们就区别开了

image.png

image.png

是啊,改变格式就可以区分开显示声明目录了,但是得自己手动加,真的很麻烦a

VitePress 实现动态获取配置侧边栏

直接上代码

import fs from "fs";
import path from "path";

function generateSidebar(dir, basePath = "") {
    let sidebar = [];
    const files = fs.readdirSync(dir, { withFileTypes: true });

    files.forEach((file) => {
        const fullPath = path.join(dir, file.name);
        const fullPathRelativeToDocs = path.relative("./docs", fullPath);

        if (file.isDirectory()) {
            // 如果是目录,递归处理 且下面没有 index.md 的情况

            const subdirBasePath = basePath ? `${basePath}/${file.name}` : file.name;
            const subdirSidebar = generateSidebar(fullPath, subdirBasePath);

            if (subdirSidebar.length > 0) {
                const obj = { text: file.name };
                obj.items = subdirSidebar;
                sidebar.push(obj);
            }
        } else if (file.name.endsWith(".md") && file.name !== "index.md") {
            // 如果是 Markdown 文件,添加到侧边栏
            // 使用 path.relative 来获取相对于 ./docs 的路径,并去除开头的 './'
            const relativePath = fullPathRelativeToDocs.startsWith(".") ? fullPathRelativeToDocs.slice(2) : fullPathRelativeToDocs;
            sidebar.push({
                text: file.name.replace(/\.md$/, ""),
                link: `/${relativePath.replace(/\\/g, "/").replace(/\.md$/, "")}`, // 将反斜杠替换为正斜杠
            });
        }
    });

    return sidebar;
}

const sidebarConfig = generateSidebar("./docs");
// console.log(JSON.stringify(sidebarConfig, null, 2)); 
let sidebar = {};
sidebarConfig.forEach((item) => {
    sidebar["/" + item.text + "/"] = item.items;
});
console.log(sidebar);
export default sidebar;

sidebarConfig是遍历文件加后的结果 文件夹下所有的md文档都会出现在对应页面的侧边栏 index.md除外 对结果处理一下 就获得我想要的结果了 引入配置 效果如下

image.png

image.png

image.png

总结

至此VitePress的动态侧边栏就完成啦 阿lin的一次尝试,如果有疑问或者更好的方案评论区发表您的意见,最后阿lin祝大家朝九晚六没班加,升职薪资嘎嘎加😀