Skip to content

路由

更新: 6/29/2025, 10:22:01 PM   字数: 0 字   时长: 0 分钟

文件路由

​  首先,新增如下目录和文件进行测试:

js
.
├─ .vitepress
│  │  └─ cache           # 开发缓存目录
│  │  └─ config.mts      # 配置文件
├─ docs        
│  ├─ chat1.md 
│  ├─ chat2.md 
│  ├─ index.md 
└─ index.md              # 主页
└─ package.json

​  生成的 HTML 页面会是这样:

docs/index.md    -->  /index.html (可以通过 / 访问)
docs/chat1.md    -->  /docs/chat1.html
docs/chat2md     -->  /docs/chat2.html

​  配置cleanUrls:true后,可以通过如下访问:

docs/chat1.md    -->  /docs/chat1
docs/chat2md     -->  /docs/chat2

​  注意:/docs/chat1/docs/chat1/ 是不一样的, 前者是访问docs/chat1.md这个文件,后者是访问docs/chat1/index.md这个文件。

导航栏

简单的下拉列表

​  首先,在config.mts同级目录下新建nav.js,并配置如下示例:

js
export default [
  { text: '主页', link: '' },
  {
    text: '示例',
    items: [
      { text: 'chat1', link: '/docs/chat1' },
      { text: 'chat2', link: '/docs/chat2' },
    ]
  }
]

​  然后在config.mts中引入./nav中的配置即可。

js
import nav from "./nav";

export default defineConfig({
  themeConfig: {
    nav: nav,
  },
})

更多的嵌套项

js
export default [
  {
    text: '分组标题',
    items: [
      {
        // 分组标题1
        text: '分组标题1',
        items: [
          { text: '分组标题1', link: '1' },
        ],
      },
      {
        // 分组标题2
        text: '分组标题2',
        items: [
          { text: '分组标题2', link: '2' },
        ],
      },
      {
        // 分组标题3
        text: '进阶玩法',
        items: [
          { text: '分组标题3', link: '3' },
        ],
      },
    ],
  },
]

侧边栏

人工配置

​  首先,在config.mts同级目录下新建sidebar.js,并配置如下示例:

js
export default {
    '/docs/': [
    {
      text: '测试',
      collapsed: false,
      items: [
        { text: 'chat1', link: '/docs/chat1'},
        { text: 'chat2', link: '/docs/chat2'},
      ]
    },
  ],
}

​  最后在config.mts中引入./sidebar.js即可。

js
import sidebar from "./sidebar"

export default defineConfig({
  themeConfig: {
    sidebar: sidebar,
  },
})

WARNING

link需要使用全路径,不能使用相对路径 否则侧边栏选中效果就会失效

'/chat2' 写成'/chat2.md''/chat2.html'效果是一样的,最佳做法是省略文件扩展名。

③ 范围大的路径需要在范围小的路径后面,否则提示错误

多个配置文件

​  若侧边栏配置较多,可以在.vitepress下新建一个sidebar文件夹单独存放所有的侧边栏配置。

js
const vitepress =  [
  {
    text: '测试',
    collapsed: false,
    items: [
      { text: 'chat1', link: '/docs/chat1'},
      { text: 'chat2', link: '/docs/chat2'},
    ]
  },
]

// 多个导出使用因为逗号分隔
// export {vite1,vite2}
export {vitepress}

​  最后在siderbar.js中引入./sidebar/webapp.js即可

js
import {vitepress} from './sidebar/webapp.js'

export default {
  '/docs/':vitepress
}

自定义脚本

警告

不建议自动配置sidebar

​  首先,将auto-gen-sidebar.mjs放到在config.mts同级目录下,然后在sidebar.js新增如下配置:

js
import { set_sidebar } from "./auto-gen-sidebar.mjs";
export default {
    // 第一个参数:常常是nav的link
    // 第二个参数:是相对于根路径的文件夹路径,返回的是每个文件夹中文件的名称和链接
    "/docs/": set_sidebar("/docs/")
}

​  特别注意,自动配置sidebar脚本生成的 访问路径 和 文件层级 是一样的,所以,是不能配置srcDir: './docs'

auto-gen-sidebar.mjs
js
import path from "node:path";
import fs from "node:fs";

// 文件根目录
const DIR_PATH = path.resolve();
// 白名单,过滤不是文章的文件和文件夹
const WHITE_LIST = [
  "index.md",
  ".vitepress",
  "node_modules",
  ".idea",
  "assets",
];

// 判断是否是文件夹
const isDirectory = (path) => fs.lstatSync(path).isDirectory();

// 取差值
const intersections = (arr1, arr2) =>
  Array.from(new Set(arr1.filter((item) => !new Set(arr2).has(item))));

// 把方法导出直接使用
function getList(params, path1, pathname) {
  // 存放结果
  const res = [];
  // 开始遍历params
  for (let file in params) {
    // 拼接目录
    const dir = path.join(path1, params[file]);
    // 判断是否是文件夹
    const isDir = isDirectory(dir);
    if (isDir) {
      // 如果是文件夹,读取之后作为下一次递归参数
      const files = fs.readdirSync(dir);
      res.push({
        text: params[file],
        collapsible: true,
        items: getList(files, dir, `${pathname}/${params[file]}`),
      });
    } else {
      // 获取名字
      const name = path.basename(params[file]);
      // 排除非 md 文件
      const suffix = path.extname(params[file]);
      if (suffix !== ".md") {
        continue;
      }
      res.push({
        text: name,
        link: `${pathname}/${name}`,
      });
    }
  }
  // 对name做一下处理,把后缀删除
  res.map((item) => {
    item.text = item.text.replace(/\.md$/, "");
  });
  return res;
}

export const set_sidebar = (pathname) => {
  // 获取pathname的路径
  const dirPath = path.join(DIR_PATH, pathname);
  // 读取pathname下的所有文件或者文件夹
  const files = fs.readdirSync(dirPath);
  // 过滤掉
  const items = intersections(files, WHITE_LIST);
  // getList 函数后面会讲到
  return getList(items, dirPath, pathname);
};

Released under the MIT License.