vuepress 设计目录及导航
官网文档
- 官网:https://v2.vuepress.vuejs.org
- 侧边栏(目录):https://v2.vuepress.vuejs.org/zh/reference/default-theme/config.html#sidebar
- 导航:https://v2.vuepress.vuejs.org/zh/reference/default-theme/config.html#navbar
需求
- 侧边栏显示目录,可以对目录顺序进行调整,目录的生成需要自动完成,对于素材文件、目录可以不显示
- 发现的其他问题解决:中文目录不展开children项。
方案设计
- 生成目录脚本获取目录结构,生成json,并建立一个用于记录隐藏文件的。
- 生成目录脚本生成目录前读取json,对于已存在的文件和目录,按照json顺序,用来满足对目录顺序调整的需求。
- 生成sidebar脚本根据目录json生成可直接用于sidebar的结构,被config.json直接引用。导航栏也可以根据目录的json进行生成。
- 其他:每个目录下要有index.md或者readme.md,不然点击目录时会显示找不到。
代码
AutoCatalog.js:生成目录文件catalog.js,目前只做了两层目录,没有递归。需要手动运行,生成catalog.js后可手动调整顺序, 文件放在docs/.vuepress/util下
const fs = require('fs');
try {
catalogOri = require('./catalog.js'); //记录手动修改过的顺序
} catch (error) {
console.log("init catalogOri")
catalogOri = {};
}
const ignoreList = ['datasource', 'hide', '.vuepress', 'Index.md']; //不在目录展示的文件
const root = '../../';
function isDirectory(item)
{
var stats = fs.statSync(item);
//console.log(item, "is Dir?", stats.isDirectory());
return stats.isDirectory();
}
function setOriItem(catalogMap, Path, List)
{
if(Path in catalogOri && catalogOri[Path].length > 0){
//console.log("List:", List, " |Path", Path, "| Ori:", catalogOri[Path]);
var tempList = catalogOri[Path].filter(item => List.includes(item)); //去掉以及被删除的内容
List.forEach(item => {
if (!tempList.includes(item)) {
console.log("new item:", item)
tempList.push(item);
}
})
catalogMap[Path] = tempList ;
} else {
catalogMap[Path] = List;
}
}
console.log("Ori:", catalogOri)
fs.readdir(root, (err, files) => {
if (err) {
console.log("err:", err);
} else {
const catalogMap = {};
const fileList = files.filter(item => !ignoreList.includes(item));
//console.log("fileList:", fileList);
setOriItem(catalogMap, '/', fileList)
fileList.forEach(item => {
if (isDirectory(root + item)) {
var Path = '/' + item;
var fileList2 = fs.readdirSync(root + item).filter(item => !ignoreList.includes(item));
setOriItem(catalogMap, Path, fileList2)
}
});
const content = `module.exports =${JSON.stringify(catalogMap, null, 2)}`;
console.log("content:", content);
fs.writeFile('./catalog.js', content, { encoding: 'utf8' }, err => { console.log(err);});
}
})
catalogtranslate.js:记录目录名翻译的map,在GetBar.js种会用到
module.exports ={
"TecNote": "技术笔记",
}
GetBar.js:读取目录json生成侧边栏和导航栏的结构体的函数,文件放在docs/.vuepress/util下
//const catalog = require('./catalog');
const translateMap = require('./catalogtranslate')
function CreateNote(item) {
var newNode = {};
if( item in translateMap) {
newNode['text'] = translateMap[item];
} else {
newNode['text'] = item;
}
newNode['link'] = '/' + item;
return newNode;
}
function GetSideBar(catalog) {
//console.log(catalog);
const sidebar = {};
for (var root in catalog) {
var List = [];
var path = '';
if (root == '/' ) {
catalog[root].forEach(item => {
List.push(CreateNote(item));
});
}
else {
path += root + '/';
catalog['/'].forEach(item => {
if(root == '/' + item) {
var newNode = CreateNote(item);
var myChildren = [];
catalog[root].forEach(item => {
myChildren.push(path + item);
});
newNode['children'] = myChildren;
//console.log(myNode);
List.push(newNode);
}
else{
List.push(CreateNote(item));
}
});
}
sidebar[root] = List;
};
console.log(JSON.stringify(sidebar));
return sidebar;
}
function GetNavBar(catalog) {
//console.log(catalog);
const navbar = [];
catalog['/'].forEach(item => {
navbar.push(CreateNote(item));
});
console.log(JSON.stringify(navbar));
return navbar;
}
export {
GetSideBar,
GetNavBar
}
修改config.js 加入引用
const catalog = require('./util/catalog');
import { GetSideBar,GetNavBar } from './util/GetBar';
在主题种配置navbar和sidebar
theme: defaultTheme({
/*
你的其他主题配置
*/
navbar: [
{
text: '导航',
children:GetNavBar(catalog),
},
{
text: '关于我',
link: '/hide/Myself'
},
],
sidebar:GetSideBar(catalog),
}),
gitcommit.sh:提交git、更新目录,本着省事的方式做了这个方案,但第一步需要单独手动执行还不是很优雅,此文档是git管理,也需要一个自动提交git的脚本,就做一起了,然后把0 0 * * * cd ${你的脚本路径} && sh gitcommit.sh 加到crontab里,每天0点自动提交。想手动提交也可以手动执行sh gitcommit.sh "your commit" , 文件放在docs外。
echo $#
if [ $# -gt 0 ]; then
message=$1
else
message="auto update file"
fi
echo $message
if [ -n "$(git status -s)" ];then
echo "new diff"
git add .
git commit -m "$message"
git push
cd docs/.vuepress/util/ && node AutoCatalog.js # update catalog
fi
效果
目录
docs
├── hide
│ └── MySelf.md
├── Index.md
├── NAS
│ ├── 软件篇.md
│ ├── 硬件篇.md
│ ├── Index.md
│ └── NAS介绍.md
└── TecNote
├── datasource
│ └── Linux下磁盘组阵列
│ ├── blkid.png
│ ├── fstab.png
│ └── GParted.png
├── Index.md
├── Linux下磁盘组阵列.md
└── vuepress设计目录及导航.md
生成的catalog.js
module.exports ={
"/": [
"NAS",
"TecNote"
],
"/NAS": [
"NAS介绍.md",
"硬件篇.md",
"软件篇.md"
],
"/TecNote": [
"Linux下磁盘组阵列.md",
"vuepress设计目录及导航.md"
]
}
页面效果: 
