sideBar.js 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. import { computed } from 'vue';
  2. import { useRoute, useData } from 'vitepress';
  3. import { useActiveSidebarLinks } from '../composables/activeSidebarLink';
  4. import { getSideBarConfig } from '../support/sideBar';
  5. export function useSideBar() {
  6. const route = useRoute();
  7. const { site } = useData();
  8. useActiveSidebarLinks();
  9. return computed(() => {
  10. // at first, we'll check if we can find the sidebar setting in frontmatter.
  11. const headers = route.data.headers;
  12. const frontSidebar = route.data.frontmatter.sidebar;
  13. const sidebarDepth = route.data.frontmatter.sidebarDepth;
  14. // if it's `false`, we'll just return an empty array here.
  15. if (frontSidebar === false) {
  16. return [];
  17. }
  18. // if it's `auto`, render headers of the current page
  19. if (frontSidebar === 'auto') {
  20. return resolveAutoSidebar(headers, sidebarDepth);
  21. }
  22. // now, there's no sidebar setting at frontmatter; let's see the configs
  23. const themeSidebar = getSideBarConfig(site.value.themeConfig.sidebar, route.data.relativePath);
  24. if (themeSidebar === false) {
  25. return [];
  26. }
  27. if (themeSidebar === 'auto') {
  28. return resolveAutoSidebar(headers, sidebarDepth);
  29. }
  30. return themeSidebar;
  31. });
  32. }
  33. function resolveAutoSidebar(headers, depth) {
  34. const ret = [];
  35. if (headers === undefined) {
  36. return [];
  37. }
  38. let lastH2 = undefined;
  39. headers.forEach(({ level, title, slug }) => {
  40. if (level - 1 > depth) {
  41. return;
  42. }
  43. const item = {
  44. text: title,
  45. link: `#${slug}`
  46. };
  47. if (level === 2) {
  48. lastH2 = item;
  49. ret.push(item);
  50. }
  51. else if (lastH2) {
  52. ;
  53. (lastH2.children || (lastH2.children = [])).push(item);
  54. }
  55. });
  56. return ret;
  57. }