Переглянути джерело

refactor sidebar && add nested demo

Pan 6 роки тому
батько
коміт
69eb3ed513

Різницю між файлами не показано, бо вона завелика
+ 1 - 0
src/icons/svg/nested.svg


+ 58 - 0
src/router/index.js

@@ -72,6 +72,64 @@ export const constantRouterMap = [
72
     ]
72
     ]
73
   },
73
   },
74
 
74
 
75
+  {
76
+    path: '/nested',
77
+    component: Layout,
78
+    redirect: '/nested/menu1',
79
+    name: 'nested',
80
+    meta: {
81
+      title: 'nested',
82
+      icon: 'nested'
83
+    },
84
+    children: [
85
+      {
86
+        path: 'menu1',
87
+        component: () => import('@/views/nested/menu1/index'), // Parent router-view
88
+        name: 'menu1',
89
+        meta: { title: 'menu1' },
90
+        children: [
91
+          {
92
+            path: 'menu1-1',
93
+            component: () => import('@/views/nested/menu1/menu1-1'),
94
+            name: 'menu1-1',
95
+            meta: { title: 'menu1-1' }
96
+          },
97
+          {
98
+            path: 'menu1-2',
99
+            component: () => import('@/views/nested/menu1/menu1-2'),
100
+            name: 'menu1-2',
101
+            meta: { title: 'menu1-2' },
102
+            children: [
103
+              {
104
+                path: 'menu1-2-1',
105
+                component: () => import('@/views/nested/menu1/menu1-2/menu1-2-1'),
106
+                name: 'menu1-2-1',
107
+                meta: { title: 'menu1-2-1' }
108
+              },
109
+              {
110
+                path: 'menu1-2-2',
111
+                component: () => import('@/views/nested/menu1/menu1-2/menu1-2-2'),
112
+                name: 'menu1-2-2',
113
+                meta: { title: 'menu1-2-2' }
114
+              }
115
+            ]
116
+          },
117
+          {
118
+            path: 'menu1-3',
119
+            component: () => import('@/views/nested/menu1/menu1-3'),
120
+            name: 'menu1-3',
121
+            meta: { title: 'menu1-3' }
122
+          }
123
+        ]
124
+      },
125
+      {
126
+        path: 'menu2',
127
+        component: () => import('@/views/nested/menu2/index'),
128
+        meta: { title: 'menu2' }
129
+      }
130
+    ]
131
+  },
132
+
75
   { path: '*', redirect: '/404', hidden: true }
133
   { path: '*', redirect: '/404', hidden: true }
76
 ]
134
 ]
77
 
135
 

+ 20 - 12
src/views/layout/components/Sidebar/SidebarItem.vue

@@ -1,26 +1,24 @@
1
 <template>
1
 <template>
2
-  <div class="menu-wrapper">
3
-    <template v-for="item in routes" v-if="!item.hidden&&item.children">
2
+  <div v-if="!item.hidden&&item.children" class="menu-wrapper">
4
 
3
 
5
-      <router-link v-if="hasOneShowingChildren(item.children) && !item.children[0].children&&!item.alwaysShow" :to="item.path+'/'+item.children[0].path"
6
-        :key="item.children[0].name">
7
-        <el-menu-item :index="item.path+'/'+item.children[0].path" :class="{'submenu-title-noDropdown':!isNest}">
4
+      <router-link v-if="hasOneShowingChildren(item.children) && !item.children[0].children&&!item.alwaysShow" :to="resolvePath(item.children[0].path)">
5
+        <el-menu-item :index="resolvePath(item.children[0].path)" :class="{'submenu-title-noDropdown':!isNest}">
8
           <svg-icon v-if="item.children[0].meta&&item.children[0].meta.icon" :icon-class="item.children[0].meta.icon"></svg-icon>
6
           <svg-icon v-if="item.children[0].meta&&item.children[0].meta.icon" :icon-class="item.children[0].meta.icon"></svg-icon>
9
           <span v-if="item.children[0].meta&&item.children[0].meta.title" slot="title">{{item.children[0].meta.title}}</span>
7
           <span v-if="item.children[0].meta&&item.children[0].meta.title" slot="title">{{item.children[0].meta.title}}</span>
10
         </el-menu-item>
8
         </el-menu-item>
11
       </router-link>
9
       </router-link>
12
 
10
 
13
-      <el-submenu v-else :index="item.name||item.path" :key="item.name">
11
+      <el-submenu v-else :index="item.name||item.path">
14
         <template slot="title">
12
         <template slot="title">
15
           <svg-icon v-if="item.meta&&item.meta.icon" :icon-class="item.meta.icon"></svg-icon>
13
           <svg-icon v-if="item.meta&&item.meta.icon" :icon-class="item.meta.icon"></svg-icon>
16
           <span v-if="item.meta&&item.meta.title" slot="title">{{item.meta.title}}</span>
14
           <span v-if="item.meta&&item.meta.title" slot="title">{{item.meta.title}}</span>
17
         </template>
15
         </template>
18
 
16
 
19
         <template v-for="child in item.children" v-if="!child.hidden">
17
         <template v-for="child in item.children" v-if="!child.hidden">
20
-          <sidebar-item :is-nest="true" class="nest-menu" v-if="child.children&&child.children.length>0" :routes="[child]" :key="child.path"></sidebar-item>
18
+          <sidebar-item :is-nest="true" class="nest-menu" v-if="child.children&&child.children.length>0" :item="child" :key="child.path" :base-path="resolvePath(child.path)"></sidebar-item>
21
 
19
 
22
-          <router-link v-else :to="item.path+'/'+child.path" :key="child.name">
23
-            <el-menu-item :index="item.path+'/'+child.path">
20
+          <router-link v-else :to="resolvePath(child.path)" :key="child.name">
21
+            <el-menu-item :index="resolvePath(child.path)">
24
               <svg-icon v-if="child.meta&&child.meta.icon" :icon-class="child.meta.icon"></svg-icon>
22
               <svg-icon v-if="child.meta&&child.meta.icon" :icon-class="child.meta.icon"></svg-icon>
25
               <span v-if="child.meta&&child.meta.title" slot="title">{{child.meta.title}}</span>
23
               <span v-if="child.meta&&child.meta.title" slot="title">{{child.meta.title}}</span>
26
             </el-menu-item>
24
             </el-menu-item>
@@ -28,20 +26,27 @@
28
         </template>
26
         </template>
29
       </el-submenu>
27
       </el-submenu>
30
 
28
 
31
-    </template>
32
   </div>
29
   </div>
33
 </template>
30
 </template>
34
 
31
 
35
 <script>
32
 <script>
33
+import path from 'path'
34
+
36
 export default {
35
 export default {
37
   name: 'SidebarItem',
36
   name: 'SidebarItem',
38
   props: {
37
   props: {
39
-    routes: {
40
-      type: Array
38
+    // route配置json
39
+    item: {
40
+      type: Object,
41
+      required: true
41
     },
42
     },
42
     isNest: {
43
     isNest: {
43
       type: Boolean,
44
       type: Boolean,
44
       default: false
45
       default: false
46
+    },
47
+    basePath: {
48
+      type: String,
49
+      default: ''
45
     }
50
     }
46
   },
51
   },
47
   methods: {
52
   methods: {
@@ -53,6 +58,9 @@ export default {
53
         return true
58
         return true
54
       }
59
       }
55
       return false
60
       return false
61
+    },
62
+    resolvePath(...paths) {
63
+      return path.resolve(this.basePath, ...paths)
56
     }
64
     }
57
   }
65
   }
58
 }
66
 }

+ 1 - 1
src/views/layout/components/Sidebar/index.vue

@@ -9,7 +9,7 @@
9
       text-color="#bfcbd9"
9
       text-color="#bfcbd9"
10
       active-text-color="#409EFF"
10
       active-text-color="#409EFF"
11
     >
11
     >
12
-      <sidebar-item :routes="routes"></sidebar-item>
12
+      <sidebar-item v-for="route in routes" :key="route.name" :item="route" :base-path="route.path"></sidebar-item>
13
     </el-menu>
13
     </el-menu>
14
   </el-scrollbar>
14
   </el-scrollbar>
15
 </template>
15
 </template>

+ 7 - 0
src/views/nested/menu1/index.vue

@@ -0,0 +1,7 @@
1
+<template >
2
+  <div style="padding:30px;">
3
+    <el-alert title="menu 1" :closable="false">
4
+      <router-view />
5
+    </el-alert>
6
+  </div>
7
+</template>

+ 7 - 0
src/views/nested/menu1/menu1-1/index.vue

@@ -0,0 +1,7 @@
1
+<template >
2
+  <div style="padding:30px;">
3
+    <el-alert title="menu 1-1" type="success" :closable="false">
4
+      <router-view />
5
+    </el-alert>
6
+  </div>
7
+</template>

+ 7 - 0
src/views/nested/menu1/menu1-2/index.vue

@@ -0,0 +1,7 @@
1
+<template>
2
+  <div style="padding:30px;">
3
+    <el-alert title="menu 1-2" type="success" :closable="false">
4
+      <router-view />
5
+    </el-alert>
6
+  </div>
7
+</template>

+ 5 - 0
src/views/nested/menu1/menu1-2/menu1-2-1/index.vue

@@ -0,0 +1,5 @@
1
+<template functional>
2
+  <div style="padding:30px;">
3
+    <el-alert title="menu 1-2-1" type="warning" :closable="false" />
4
+  </div>
5
+</template>

+ 5 - 0
src/views/nested/menu1/menu1-2/menu1-2-2/index.vue

@@ -0,0 +1,5 @@
1
+<template functional>
2
+  <div style="padding:30px;">
3
+    <el-alert title="menu 1-2-2" type="warning" :closable="false" />
4
+  </div>
5
+</template>

+ 5 - 0
src/views/nested/menu1/menu1-3/index.vue

@@ -0,0 +1,5 @@
1
+<template functional>
2
+  <div style="padding:30px;">
3
+    <el-alert title="menu 1-3" type="success" :closable="false" />
4
+  </div>
5
+</template>

+ 5 - 0
src/views/nested/menu2/index.vue

@@ -0,0 +1,5 @@
1
+<template>
2
+  <div style="padding:30px;">
3
+    <el-alert title="menu 2" :closable="false" />
4
+  </div>
5
+</template>