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