递归函数 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

相关文章
相关标签/搜索