阅读 536

VuePress,自动生成侧边栏,侧边栏自动化

(博主使用的VuePress版本是1.x的,希望你看的时候先注意自己的版本,2.x的不确定可以使用)

如题,博主和大部分的程序员一样,偶尔会喜欢写写文档,年纪大了,很多东西都记不住了,还是写出来比较实在.

使用VuePress很久了,创建自动化也很久了(一两年了),今天闲着没事,搞了一下,弄个文章吧,希望能帮到有需求的人

为了不偏题,和文档相关的那些就不赘述了.大部分人搜索这个只是为了找到一个好用的教程.

不要问我为什么不发布到npm(比较懒,而且这么点代码没必要)

不要问Nav(导航栏)能不能自动化(不要提需求)

不要说啥啥啥不能用(女留微信,男自强)

文件目录

那先看看我的文件目录

image.png

这次用到的主力文件有两个,一个utils/index.js,另外一个是config.js(这个配置文件是Vuepress官方的配置文件 )

如图,view是我存放文档的目录 不要问我为什么根目录的文件名不是docs,而是src(可以换的,你们不知道吗?) 你可以参考我的目录结构来更改(都是可选项啦)

上手代码

utils/index.js

const PATH = require('path') const fs = require('fs') // 字符串工具类 const str = {     /**      * 两个字符串是否相同      * @param {String} string 第一个字符串      * @param {String} substr 第二个字符串      * @param {Boolean} isIgnoreCase 是否忽略大小写      * @returns {Boolean} 相同为真,不同为假      */     contains: (string, substr, isIgnoreCase) => {         //  大小转换成小写         if (isIgnoreCase) {             // toLowerCase() :把字符串转换为小写             string = string.toLowerCase()             substr = substr.toLowerCase()         }         // 截取单个字符         let startChar = substr.substring(0, 1)         // 获取字符串长度         let strLen = substr.length         for (let i = 0; i < string.length - strLen + 1; i++) {             // charAt() :返回指定位置的字符             if (string.charAt(i) === startChar) {                 // 如果从i开始的地方两个字符串一样,那就一样                 if (string.substring(i, i + strLen) === substr) { return true }             }         }         return false     } } /**  * 自定义排序文件夹  * @param  a  * @param  b  * @returns  { number }  */ function sortDir (a, b) {     let al = a.parent.toString().split("\\").length     let bl = b.parent.toString().split("\\").length     if (al > bl) {         return -1     }     if (al === bl) {         return 0     }     if (al < bl) {         return 1     } } // 文件助手 const filehelper = {     /**      *       * @param {String} rpath 目录路径      * @param {Array} unDirIncludes 需要排除的某些目录(文件夹)      * @param {Array} SuffixIncludes 需要处理的文件后缀      * @returns       */     getAllFiles: (rpath, unDirIncludes, SuffixIncludes) => {         let filenameList = []         fs.readdirSync(rpath).forEach((file) => {             let fileInfo = fs.statSync(rpath + '\\' + file)             if (fileInfo.isFile() && !unDirIncludes.includes(file) && !str.contains(file, "img", true)) {                 // 只处理固定后缀的文件                 if (SuffixIncludes.includes(file.split('.')[1])) {                     //  过滤readme.md文件                     if (file === 'readme.md' || file === 'README.md') {                         file = ''                     } else {                         //  截取MD文档后缀名                         file = file.replace('.md', '')                     }                     filenameList.push(file)                 }             }         })         //  排序         filenameList.sort()         return filenameList     },     /**      *       * @param {String} mypath 当前的目录路径      * @param {Array} unDirIncludes 需要排除的某些目录(文件夹)      * @returns {Array} result 所有的目录      */     getAllDirs: function getAllDirs (mypath = ".", unDirIncludes,) {         // 获取目录数据         const items = fs.readdirSync(mypath)         let result = []         // 遍历目录中所有文件夹         items.map(item => {             let temp = PATH.join(mypath, item)             // isDirectory() 不接收任何参数,如果是目录(文件夹)返回true,否则返回false             // 如果是目录,且不包含如下目录             if (fs.statSync(temp).isDirectory() && !item.startsWith(".") && !unDirIncludes.includes(item)) {                 result.push(mypath + '\\' + item + '\\')                 result = result.concat(getAllDirs(temp, unDirIncludes))             }         })         return result     } } // 侧边栏创建工具 const sideBarTool = {     /**      * 创建一个侧边栏,支持多层级递归      * @param {String} RootPath 目录路径      * @param {Array} unDirIncludes 需要排除的某些目录(文件夹)      * @param {Array} SuffixIncludes 需要处理的文件后缀      * @returns {Object} 返回一个对象,如下所示      *       * {      * '/view/GFW/': [ 'index' ],      * '/view/git/': [ 'index' ],      * '/view/html/': [ 'day1', 'day2', 'day3', 'day4', 'day5' ],      * }      *       */     genSideBar: (RootPath, unDirIncludes, SuffixIncludes) => {         let sidebars = {}         let allDirs = filehelper.getAllDirs(RootPath, unDirIncludes)         allDirs.forEach(item => {             let dirFiles = filehelper.getAllFiles(item, unDirIncludes, SuffixIncludes)             let dirname = item.replace(RootPath, "")             dirname = dirname.replace(/\\/g, '/')             if (dirFiles.length > 0) {                 sidebars[dirname] = dirFiles             }         })         return sidebars     },     /**      * 创建一个侧边栏(带分组),支持多层级递归      * @param {String} RootPath 目录路径      * @param {Array} unDirIncludes 需要排除的某些目录(文件夹)      * @param {Array} SuffixIncludes 需要处理的文件后缀      * @param {Object} param3 暂未用上(分组相关配置参数)      * @returns {Array} 返回一个数组,如下所示      * [{      *  "title": "",      *  "collapsable": true,      *  "sidebarDepth": 2,      *  "children": ["/view/"]      *   },      *  {      *  "title": "GFW",      *   "collapsable": true,      *   "sidebarDepth": 2,      *  "children": ["/view/GFW/"]      *  },      *  {      *  "title": "html",      *  "collapsable": true,      *  "sidebarDepth": 2,      *  "children": [      *      ["/view/html/day1", "day1"],      *      ["/view/html/day2", "day2"],      *      ["/view/html/day3", "day3"],      *      ["/view/html/day4", "day4"],      *      ["/view/html/day5", "day5"]      *    ]      * }]      */     genSideBarGroup: (RootPath, unDirIncludes, SuffixIncludes, { title = '', children = [''], collapsable = true, sidebarDepth = 2 }) => {         // 准备接收         let sidebars = []         let allDirs = filehelper.getAllDirs(RootPath, unDirIncludes)         allDirs.forEach((item) => {             let children = filehelper.getAllFiles(item, unDirIncludes, SuffixIncludes)             let dirname = item.replace(RootPath, "")             let titleTemp = item.replace(RootPath + '\\view', "")             title = titleTemp.replace(/\\/g, '')             if (children.length > 1) {                 children = children.flatMap((vo, idx) => [[dirname.replace(/\\/g, '/') + vo, vo]])             }             let Obj = {                 title,                 collapsable: true,                 sidebarDepth: 2,                 children: children.length > 1 ? children : [dirname.replace(/\\/g, '/')]             }             sidebars.push(Obj)         })         return sidebars     } } module.exports = { str, filehelper, sideBarTool } 复制代码

config.js

    //导入生成侧边栏的工具类 const { sideBarTool } = require(path.join(__dirname, './utils/index.js')) // 需要排除的一些目录 let unDirIncludes = ['node_modules', 'assets', 'public', '网络工程'] // 只需要处理后缀的文件类型 let SuffixIncludes = ['md', 'html']     //使用方法生生成侧边栏 // 侧边栏 let sidebar = sideBarTool.genSideBarGroup(rootPath, unDirIncludes, SuffixIncludes, {}) 复制代码

如何使用

自动化

如果你和我一样,文件目录很多,想给侧边栏分组,支持折叠打开,那就使用sideBarTool.genSideBarGroup()

该方法返回一个分完组的sidebar对象数组,如下图(VuePress官网的配置项图片)

image.png

如果你不想分组,就想有个自动化的侧边栏而已,那你可以使用sideBarTool.genSideBar() 该方法返回一个对象,如下图所示(VuePress官网的配置项图片)

[该配置需要你目录结构保持一致]

image.png

如果你还不清楚或者分不清,那我建议你先看看官方文档

侧边栏配置

手动档

当然,我知道有些同学喜欢手动化配置,比如分组的时候,collapsable参数他想设置为false,或者sidebarDepth 参数设置为1,3,等等,那你可以修改上面提供的源码,来达到你的目的.或者在掘金搜索,或者等我更新(比较懒,估计不更新了)

思路很简单,遍历出文件目录,生成一个对象或者数组,相应的代码文中已经有了,你可以自己研究下

总结

3个步骤

  • 创建一个index.js(你想改成啥名字都可以,在哪个路径都可以,只要你找的到)

复制本文的utils/index.js所有内容,粘贴到你创建的这个index.js里面(已经很人性化,都告诉你粘贴到哪里了)

  • config.js导入

为了防止某些人看不明白,就勉为妻难的贴个图吧

image.png

  • 掉用方法,得到生成的数据后赋值到指定位置


作者:nullhan
链接:https://juejin.cn/post/7045168740643635237

玩站网免费分享SEO网站优化 技术及文章 伪原创工具 https://www.237it.com/ 


文章分类
代码人生
文章标签
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐