遞歸函數 Vue ElementUI

對樹形菜單的遞歸操做,首先應該對樹形菜單數據進行整理,優化成本身須要的類型 
好比Vue + ElementUI的動態側邊欄數據
 1 export function routerRoleToPretty (routing = [], deepPath = '/main/') {
 2   return routing.map(item => {
 3     if (item instanceof Array) { // 因爲後臺返回數據問題 因此這裏給了一個兼容判斷  4       return item[0]
 5     } else {
 6       return item
 7     }
 8   }).map(item => {
 9     return {
10       id: item.id,
11       path: item.path,
12       name: item.name,  // 也可經過name方式跳轉 13       fullPath: `${deepPath + item.path}`, // 這裏咱們獲取到VueRouter的絕對路由 經過path的方式去進行跳轉頁面 14       meta: { // meta 中參數用來肯定顯示問題 15         icon: item.icon,
16         childrenLength: item.ziJi_1 ? item.ziJi_1.length : 0,
17         enTitle: item.enTitle,
18         zhTitle: item.zhTitle,
19         desc: item.description,
20         type: item.type,
21         parentId: item.parentId
22       },
23       children: routerRoleToPretty(item.ziJi_1 ? item.ziJi_1 : [], deepPath + item.path + '/')
24     }
25   })
26 }

因爲後臺返回的數據格式是 [[{}], [{}]]格式因此第一次須要將數據暴露出css

這樣一個遞歸就完成了數據處理vue

 

固然若是你想將遞歸數據所有取出來EcmaScript提供了一個方法 Array.prototype.flat()vuex

var arr1 = [1, 2, [3, 4]];
arr1.flat(); 
// [1, 2, 3, 4]

當參數爲 Infinity 時不限制遞歸數據深度 這樣就能夠獲取到全部隊規的對象 而後再去 map() 操做就很簡單啦api

var arr3 = [1, 2, [3, 4, [5, 6]]];
// 使用 Infinity 做爲深度,展開任意深度的嵌套數組
arr3.flat(Infinity);
// [1, 2, 3, 4, 5, 6]

最後貼上ElementUI如何使用遞歸數據數組

父級組件sass

  1 <!-- 左側菜單導航欄組件 -->
  2 <template>
  3   <scroll-bar>
  4     <slot></slot>
  5     <div class="app-nav-wrap">
  6       <el-menu mode="vertical"
  7         popper-class="roleMenuClass"
  8         :default-active="routerAction"
  9         :class="{'menu-nav': true, 'isCollapse': isCollapse}"
 10         :unique-opened="true"
 11         @open="handleOpen"
 12         @close="handleClose"
 13         :collapse="isCollapse"
 14         background-color="#0A70F8"
 15         text-color="#fff"
 16         router>
 17         <rm-menu :childrenData="routerMenu"></rm-menu>
 18       </el-menu>
 19     </div>
 20   </scroll-bar>
 21 </template>
 22 
 23 <script>
 24 import { mapGetters, mapActions } from 'vuex'
 25 import SystemConfigModule from '@/utils/api/System'
 26 import RmMenu from './RecursiveMenu'
 27 import ScrollBar from '@/components/common/ScrollBar'
 28 // import { getHistoryRouter } from '@/utils/cookie'
 29 export default {
 30   components: { RmMenu, ScrollBar },
 31   data () {
 32     return {
 33       routerMenu: [],
 34       routerAction: this.$route.path
 35     }
 36   },
 37   watch: {
 38     '$route' (to) {
 39       this.routerAction = to.path
 40     }
 41   },
 42   created () {
 43     this.rulesChange()
 44   },
 45   computed: {
 46     ...mapGetters([
 47       'sliderbar'
 48     ]),
 49     options () {
 50       return this.$store.state.options
 51     },
 52     isCollapse () {
 53       return this.sliderbar
 54     }
 55   },
 56   methods: {
 57     ...mapActions({
 58       UpdateRouterRole: 'UpdateRouterRole'
 59     }),
 60     handleOpen (key, keyPath) {
 61       // console.log(key, keyPath)
 62     },
 63     handleClose (key, keyPath) {
 64       // console.log(key, keyPath)
 65     },
 66     async rulesChange () {
 67       this.routerMenu = await this.UpdateRouterRole(SystemConfigModule.SystemModule.MenuRole)
 68       // console.log(this.routerMenu)
 69     }
 70   }
 71 }
 72 </script>
 73 <style lang="scss" scoped>
 74   @import '@/assets/sass/theme.sass';
 75   /deep/ .app-nav-wrap {
 76     .menu-nav:not(.el-menu--collapse) {
 77       width: 200px;
 78       // min-height: 400px;
 79       min-width: 36px;
 80       .menulist {
 81         background-color: $menuBg !important;
 82         transition: all .5s linear;
 83         // 展開樣式
 84         .el-submenu.is-opened {
 85           .el-menu.el-menu--inline {
 86             .el-menu-item {
 87               background-color: $subMenuBg !important;
 88               transition: all .5s linear;
 89               &.is-active {
 90                 background-color: $menuHover !important;
 91                 transition: all .5s linear;
 92               }
 93             }
 94           }
 95         }
 96         // 樣式
 97         li.el-menu-item,.el-submenu__title {
 98           &:hover {
 99             background-color: $menuHover;
100             transition: all .5s linear;
101           }
102         }
103         // 高亮
104         a.router-link-active li.el-menu-item.is-active,
105         .el-menu-item.is-active{
106           background-color: $menuHover !important;
107           transition: all .5s linear;
108         }
109         .el-submenu__title,
110         .el-menu-item {
111           color: $fontColor;
112           transition: all .5s linear;
113         }
114         .el-submenu__icon-arrow.el-icon-arrow-down {
115           color: $fontColor;
116         }
117       }
118     }
119     // 小的菜單欄數據
120     .isCollapse{
121       width: 36px;
122       .menulist{
123         background-color: $menuBg !important;
124         transition: all .5s linear;
125         .el-submenu .el-submenu__title{
126           padding: 0 !important;
127           span{
128             display: none;
129           }
130           .icon-menu{
131             margin: 0;
132             font-size: 16px;
133             padding: 15px 8px;
134           }
135           i.el-submenu__icon-arrow{
136             display: none;
137             color: $fontColor;
138           }
139         }
140         // 樣式
141         li.el-menu-item{
142           padding: 0 !important;
143           span{
144             display: none;
145           }
146           .icon-menu{
147             margin: 0;
148             font-size: 16px;
149             padding: 15px 8px;
150           }
151         }
152         // hover樣式
153         li.el-menu-item,.el-submenu__title {
154           &:hover {
155             background-color: $menuHover;
156             transition: all .5s linear;
157           }
158         }
159         // 高亮
160         li.el-menu-item.is-active,
161         li.el-submenu.is-active {
162           background-color: $menuHover !important;
163           transition: all .5s linear;
164           // 更改默認繼承
165           .el-submenu__title {
166             background-color: inherit !important;
167           }
168         }
169       }
170     }
171     .menulist a.router-link-exact-active.router-link-active li.el-menu-item.is-active{
172       background-color: $menuHover !important;
173       transition: all .5s linear;
174     }
175     i.icon-menu {
176       color: #fff;
177     }
178   }
179 </style>
180 <style lang="scss">
181   @import '@/assets/sass/theme.sass';
182   .roleMenuClass {
183     .menulist {
184       background-color: $menuBg !important;
185       transition: all .5s linear;
186       // 展開樣式
187       .el-submenu.is-opened {
188         .el-menu.el-menu--inline {
189           .el-menu-item {
190             background-color: $subMenuBg !important;
191             transition: all .5s linear;
192             &.is-active {
193               background-color: $menuHover !important;
194               transition: all .5s linear;
195             }
196           }
197         }
198       }
199       li.el-menu-item,.el-submenu__title {
200         &:hover {
201           background-color: $menuHover;
202           transition: all .5s linear;
203         }
204       }
205       a.router-link-active li.el-menu-item.is-active,
206       .el-menu-item.is-active{
207         background-color: $menuHover !important;
208         transition: all .5s linear;
209       }
210       .el-submenu__title,
211       .el-menu-item {
212         color: $fontColor;
213         transition: all .5s linear;
214       }
215       .el-submenu__icon-arrow.el-icon-arrow-down {
216         color: $fontColor;
217       }
218     }
219     /deep/ .menulist a.router-link-exact-active.router-link-active li.el-menu-item.is-active{
220       background-color: $menuHover !important;
221       transition: all .5s linear;
222     }
223     i.icon-menu {
224       color: #fff;
225     }
226   }
227 </style>

子組件 RecursiveMenu.vuecookie

 1 <template>
 2   <section class="menulist">
 3     <section v-for="item in childrenData" :key="item.id">
 4       <!-- 沒有子集的 -->
 5       <el-menu-item :index="item.fullPath" v-if="item.meta.childrenLength === 0">
 6         <i :class="['icon-menu', 'iconfont', item.meta.icon]"></i>
 7         <span>{{langChange() ? item.meta.zhTitle : item.meta.enTitle}}</span>
 8       </el-menu-item>
 9       <!-- 子集只有一個的 只展現子集 -->
10       <el-menu-item :index="item.children[0].fullPath" v-if="item.meta.childrenLength === 1">
11         <i :class="['icon-menu', 'iconfont', item.meta.icon]"></i>
12         <span>{{langChange() ? item.children[0].meta.zhTitle : item.children[0].meta.enTitle}}</span>
13       </el-menu-item>
14       <!-- 子集大於一個的 -->
15       <el-submenu :popper-append-to-body="true" popper-class="roleMenuClass" v-if="item.meta.childrenLength > 1" :index="item.fullPath">
16         <template slot="title">
17           <i :class="['icon-menu', 'iconfont', item.meta.icon]"></i>
18           <span v-if="item.meta && item.meta.zhTitle && item.meta.enTitle">{{langChange() ? item.meta.zhTitle : item.meta.enTitle}}</span>
19         </template>
20         <rm-menu :childrenData="item.children"></rm-menu>
21       </el-submenu>
22     </section>
23   </section>
24 </template>
25 <script>
26 import { mapGetters } from 'vuex'
27 export default {
28   name: 'RmMenu',
29   data () {
30     return {}
31   },
32   computed: {
33     ...mapGetters([
34       'lang'
35     ])
36   },
37   props: {
38     childrenData: {
39       default: () => [],
40       type: Array
41     }
42   },
43   methods: {
44     langChange () {
45       if (this.lang === 'zh') {
46         return true
47       } else {
48         return false
49       }
50     }
51   }
52 }
53 </script>

至此結束app

相關文章
相關標籤/搜索