# Vuepress 自动侧边栏 ## 需求 Vuepress 默认提供了几种侧边栏的实现方式,但都是需要手动去 config.js 中配置的,也就是每次添加文章后都需要在 config.js 中添加侧边栏,虽然 Vuepress 也提供了一个自动侧边栏的功能,但这个方法比较局限,只是正对某一篇文章且仅仅包含了当前页面标题(headers)链接的侧边栏。 而我需要的是一个只要每次添加文章后,Vuepress 就能自动生成响应的侧边了,不需要额外的配置。 ## 思路 1. 通过 Node.js 的 fs 方法递归获取 docs 目录下的所有文件夹/文件名称 2. 把获取的文件夹/文件名称以[多个侧边栏](https://v1.vuepress.vuejs.org/zh/theme/default-theme-config.html#%E5%A4%9A%E4%B8%AA%E4%BE%A7%E8%BE%B9%E6%A0%8F)的形式自动写到 config.js 的 sidebar 属性中 ## 实现方法 1. 在 docs 根目录下新建 `utils/autoSidebar.js` 直接上代码,因为功能比较简单,就直接写在一个文件里了,没有做分拆 ```js const fs = require('fs') const path = require('path') const { sep } = path const rootpath = path.resolve(path.dirname(__dirname), 'docs') // 根目录 let pathArr = [] // 读取目录 let readDir = folderPath => { let exists = fs.existsSync(folderPath), stat = fs.statSync(folderPath) if (exists && stat) { //判断文件、文件目录是否存在 if (stat.isFile()) { let tempArr = folderPath.replace(rootpath + sep, '').split(sep) // 去除根目录部分,并分割成数组 // 大于 1 可排除根目录下的 'README.md' if (tempArr.length > 1) { pathArr.forEach(item => { // 如果 pathArr 中已经有相同目录则直接 push .md 文件 if (item.join(sep).indexOf(tempArr.slice(0, -1).join(sep)) != -1) { item.push(tempArr.pop()) } }) // 排除没有 .md 的目录 if (tempArr[tempArr.length - 1].indexOf('.md') > 0) pathArr.push(tempArr) } } else if (stat.isDirectory()) { let files = fs.readdirSync(folderPath) if (files && files.length > 0) { files.forEach(function(file) { if (file != '.vuepress') { // 排除 .vuepress 目录 readDir(folderPath + sep + file) //递归 } }) } } } } readDir(rootpath) // console.log('pathArr:', pathArr); let getSidebar = (title, children = ['']) => { let arr = [] arr.push({ title, children }) return arr } let sidebar = {} pathArr.forEach(item => { let children = [] let link = '' let title = '' item.forEach(key => { if (key.indexOf('.md') > 0) { if (key === 'README.md') key = '' children.push(key.replace(/\.md/gi, '')) } else { link += `${key}/` title = key } }) sidebar[`/${link}`] = getSidebar(title, children) }) // console.log('sidebar:', sidebar); module.exports = sidebar ``` 2. 在 config.js 中引入 ```js const sidebar = require('../../utils/autoSidebar') module.exports = { // ... 省略无关代码 themeConfig: { // ... 省略无关代码 sidebarDepth: 2, sidebar: sidebar } // ... 省略无关代码 } ``` ## 目录结构 ![目录结构](/public/uploads/2019/11/28/1574902701872755.png "目录结构") 实际生成后的目录类似: ```js sidebar: { '/guide/': [ { title: 'Guide', collapsable: false, children: [ '', 'using-vue', ] } ], } ``` ## 总结 如果你比我还懒的话,连 nav 也不想自己手动配置的话,也可以用上面的方法修改一下来实现。 在这个小功能中主要用的其实就是 Node.js 的入门知识,对于前端开发来说,掌握一定的 Node.js 在实际工作当中还是有一定帮助的。