SidebarLinks 1.vue 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. <template>
  2. <ul
  3. class="sidebar-links"
  4. v-if="items.length"
  5. >
  6. <li v-for="(item, i) in items" :key="i">
  7. <SidebarGroup
  8. v-if="item.type === 'group'"
  9. :item="item"
  10. :open="i === openGroupIndex"
  11. :collapsable="item.collapsable || item.collapsible"
  12. :depth="depth"
  13. @toggle="toggleGroup(i)"
  14. />
  15. <SidebarLink
  16. v-else
  17. :sidebarDepth="sidebarDepth"
  18. :item="item"
  19. />
  20. </li>
  21. </ul>
  22. </template>
  23. <script>
  24. import SidebarGroup from '@theme/components/SidebarGroup.vue'
  25. import SidebarLink from '@theme/components/SidebarLink.vue'
  26. import { isActive } from '../util'
  27. export default {
  28. name: 'SidebarLinks',
  29. components: { SidebarGroup, SidebarLink },
  30. props: [
  31. 'items',
  32. 'depth', // depth of current sidebar links
  33. 'sidebarDepth' // depth of headers to be extracted
  34. ],
  35. data () {
  36. return {
  37. openGroupIndex: 0
  38. }
  39. },
  40. created () {
  41. this.refreshIndex()
  42. },
  43. watch: {
  44. '$route' () {
  45. this.refreshIndex()
  46. }
  47. },
  48. methods: {
  49. refreshIndex () {
  50. const index = resolveOpenGroupIndex(
  51. this.$route,
  52. this.items
  53. )
  54. if (index > -1) {
  55. this.openGroupIndex = index
  56. }
  57. },
  58. toggleGroup (index) {
  59. this.openGroupIndex = index === this.openGroupIndex ? -1 : index
  60. },
  61. isActive (page) {
  62. return isActive(this.$route, page.regularPath)
  63. }
  64. }
  65. }
  66. function resolveOpenGroupIndex (route, items) {
  67. for (let i = 0; i < items.length; i++) {
  68. const item = items[i]
  69. if (descendantIsActive(route, item)) {
  70. return i
  71. }
  72. }
  73. return -1
  74. }
  75. function descendantIsActive (route, item) {
  76. if (item.type === 'group') {
  77. return item.children.some(child => {
  78. if (child.type === 'group') {
  79. return descendantIsActive(route, child)
  80. } else {
  81. return child.type === 'page' && isActive(route, child.path)
  82. }
  83. })
  84. }
  85. return false
  86. }
  87. </script>