2021-03-01 15:06:11 +08:00

90 lines
3.0 KiB
JavaScript

import { useRoute, useSiteDataByRoute } from 'vitepress';
import { computed } from 'vue';
import { getPathDirName } from '../utils';
import { useActiveSidebarLinks } from '../composables/activeSidebarLink';
import NavBarLinks from './NavBarLinks.vue';
import { SideBarItem } from './SideBarItem';
export default {
components: {
NavBarLinks,
SideBarItem
},
setup() {
const route = useRoute();
const siteData = useSiteDataByRoute();
useActiveSidebarLinks();
return {
items: computed(() => {
const { headers, frontmatter: { sidebar, sidebarDepth = 2 } } = route.data;
if (sidebar === 'auto') {
// auto, render headers of current page
return resolveAutoSidebar(headers, sidebarDepth);
}
else if (Array.isArray(sidebar)) {
// in-page array config
return resolveArraySidebar(sidebar, sidebarDepth);
}
else if (sidebar === false) {
return [];
}
else {
// no explicit page sidebar config
// check global theme config
const { sidebar: themeSidebar } = siteData.value.themeConfig;
if (themeSidebar === 'auto') {
return resolveAutoSidebar(headers, sidebarDepth);
}
else if (Array.isArray(themeSidebar)) {
return resolveArraySidebar(themeSidebar, sidebarDepth);
}
else if (themeSidebar === false) {
return [];
}
else if (typeof themeSidebar === 'object') {
return resolveMultiSidebar(themeSidebar, route.path, headers, sidebarDepth);
}
}
})
};
}
};
function resolveAutoSidebar(headers, depth) {
const ret = [];
if (headers === undefined) {
return [];
}
let lastH2 = undefined;
headers.forEach(({ level, title, slug }) => {
if (level - 1 > depth) {
return;
}
const item = {
text: title,
link: `#${slug}`
};
if (level === 2) {
lastH2 = item;
ret.push(item);
}
else if (lastH2) {
;
(lastH2.children || (lastH2.children = [])).push(item);
}
});
return ret;
}
function resolveArraySidebar(config, depth) {
return config;
}
function resolveMultiSidebar(config, path, headers, depth) {
const paths = [path, Object.keys(config)[0]];
const item = paths.map((x) => config[getPathDirName(x)]).find(Boolean);
if (Array.isArray(item)) {
return resolveArraySidebar(item, depth);
}
if (item === 'auto') {
return resolveAutoSidebar(headers, depth);
}
return [];
}