实现不限层级的Element的NavMenu

做管理后台开发的时候,需要用到Element的NavMenu组件,于是乎,翻开文档,大致是这样实现的。

<el-menu>
   <el-menu-item index="1">标题一</el-menu-item>
   <el-submenu index="2">
      <template slot="title">标题二</template>
      <el-menu-item index="2-1">选项1</el-menu-item>
   </el-submenu>
</el-menu>

非常简单,But,实际开发中,就不是这么一回儿事儿了,我们的导航菜单,层级是不确定的。有可能是一层,有可能是两层,有可能是三层,崩溃不崩溃。按照这个中规中矩的写法,似乎要写到天荒地老了。
我们来梳理一下如何实现。

  • 一层,使用elMenuItem,很好~
  • 二层,使用elSubmenu嵌套elMenuItem,很好~
  • 三层,使用elSubmenu嵌套elMenuItem嵌套elSubmenu,不太好了
  • ...

是不是联想起来什么了,对,递归。
赶紧翻翻vue文档吧,果真,有一种叫做递归组件的东西,说白了,就是组件中再调用组件。(注意:递归组件一定要记得写好name属性)
所以,赶紧实现一下吧。
先来写一下需要递归的NavMenu组件

 <!-- 递归菜单 -->
 <el-menu default-active="0" class="el-menu-demo" mode="horizontal" @select="handleSelect">
    <nav-menu :navMenus="asideMenu"></nav-menu>
 </el-menu>
 <!-- 递归菜单结束 -->

然后写一下NavMenu组件

复制代码
<template>
    <div class="nav-menu">
        <el-menu-item v-for="navMenu in noChildren" :index="navMenu.id" :key="navMenu.id">
            <span slot="title" @click="clickMenu(navMenu)">{{navMenu.name}}</span>
        </el-menu-item>
        <el-submenu v-for="navMenu in hasChildren" :key="navMenu.id" :index="navMenu.id">
            <template slot="title" @click="clickMenu(navMenu)">
                <span>{{navMenu.name}}</span>
            </template>
            <nav-menu :navMenus="navMenu.children"></nav-menu>
        </el-submenu>
    </div>
</template>

<script>
export default {
    name: 'NavMenu',
    props: {
        navMenus: Array
    },
    computed: {
        noChildren() {
            return this.navMenus.filter(item => item.children.length === 0);
        },
        hasChildren() {
            return this.navMenus.filter(item => item.children.length > 0);
        }
    },
    data() {
        return {};
    },
    methods: {
        clickMenu(menu) {
            this.$store.commit('SET_MENU', menu);
            this.$router.push({
                path: menu.link
            });
        }
    }
};
</script>
复制代码
后台返的数据结构:
复制代码
  1 {
  2     "data":[
  3         {
  4             "parent":"0",
  5             "from_store":"",
  6             "lock_status":"0",
  7             "open_type":"1",
  8             "level":"1",
  9             "link":"",
 10             "icon_name":"qy-service_appointment",
 11             "personalize":"0",
 12             "jump_addr":"",
 13             "icon_color":"#2aaa91",
 14             "children":[
 15 
 16             ],
 17             "name":"流程",
 18             "id":"1",
 19             "package_version_code":"",
 20             "showChildren":false
 21         },
 22         {
 23             "parent":"0",
 24             "from_store":"",
 25             "lock_status":"0",
 26             "open_type":"1",
 27             "level":"1",
 28             "link":"",
 29             "icon_name":"qy-service_appointment",
 30             "personalize":"0",
 31             "jump_addr":"",
 32             "icon_color":"#2aaa91",
 33             "children":[
 34 
 35             ],
 36             "name":"Info",
 37             "id":"2",
 38             "package_version_code":"",
 39             "showChildren":false
 40         },
 41         {
 42             "parent":"0",
 43             "from_store":"",
 44             "app_type":"",
 45             "lock_status":"0",
 46             "open_type":"1",
 47             "level":"1",
 48             "link":"",
 49             "description":"",
 50             "icon_name":"qy-performance",
 51             "personalize":"0",
 52             "jump_addr":"",
 53             "icon_color":"#54698d",
 54             "children":[
 55                 {
 56                     "app_show":"1",
 57                     "parent":"3",
 58                     "from_store":"",
 59                     "app_type":"information",
 60                     "lock_status":"0",
 61                     "web_show":"1",
 62                     "open_type":"1",
 63                     "level":"2",
 64                     "link":"/app/!/information/yonghubiao",
 65                     "description":"",
 66                     "icon_name":"qy-lead",
 67                     "personalize":"0",
 68                     "jump_addr":"",
 69                     "icon_color":"#00cdc0",
 70                     "children":[
 71 
 72                     ],
 73                     "name":"用户表",
 74                     "id":"4",
 75                     "app_id":"yonghubiao",
 76                     "package_version_code":"",
 77                     "showChildren":false,
 78                     "order":"0"
 79                 },
 80                 {
 81                     "app_show":"1",
 82                     "parent":"3",
 83                     "from_store":"",
 84                     "app_type":"information",
 85                     "lock_status":"0",
 86                     "web_show":"1",
 87                     "open_type":"1",
 88                     "level":"2",
 89                     "link":"/app/!/information/pingjifufenjisuangui",
 90                     "description":"",
 91                     "icon_name":"qy-contract",
 92                     "personalize":"0",
 93                     "jump_addr":"",
 94                     "icon_color":"#fcb95b",
 95                     "children":[
 96 
 97                     ],
 98                     "name":"评级赋分计算规则",
 99                     "id":"22",
100                     "app_id":"pingjifufenjisuangui",
101                     "package_version_code":"",
102                     "showChildren":false,
103                     "order":"0"
104                 },
105                 {
106                     "app_show":"1",
107                     "parent":"3",
108                     "from_store":"",
109                     "app_type":"link",
110                     "lock_status":"0",
111                     "web_show":"1",
112                     "open_type":"1",
113                     "level":"2",
114                     "link":"https://www.baidu.com",
115                     "description":"",
116                     "icon_name":"qy-case_comment",
117                     "personalize":"0",
118                     "jump_addr":"",
119                     "icon_color":"#8199af",
120                     "children":[
121 
122                     ],
123                     "name":"baidu",
124                     "id":"23",
125                     "package_version_code":"",
126                     "showChildren":false,
127                     "order":"0"
128                 },
129                 {
130                     "app_show":"1",
131                     "parent":"3",
132                     "from_store":"",
133                     "app_type":"",
134                     "lock_status":"0",
135                     "web_show":"1",
136                     "open_type":"1",
137                     "level":"2",
138                     "link":"",
139                     "description":"",
140                     "icon_name":"",
141                     "personalize":"0",
142                     "jump_addr":"",
143                     "icon_color":"",
144                     "children":[
145                         {
146                             "app_show":"1",
147                             "parent":"6",
148                             "from_store":"",
149                             "app_type":"information",
150                             "lock_status":"0",
151                             "web_show":"1",
152                             "open_type":"1",
153                             "level":"3",
154                             "link":"/app/!/information/jianchawenjuan",
155                             "description":"",
156                             "icon_name":"qy-question_best",
157                             "personalize":"0",
158                             "jump_addr":"",
159                             "icon_color":"#e6717c",
160                             "children":[
161 
162                             ],
163                             "name":"检查问卷",
164                             "id":"9",
165                             "app_id":"jianchawenjuan",
166                             "package_version_code":"",
167                             "showChildren":false,
168                             "order":"0"
169                         },
170                         {
171                             "app_show":"1",
172                             "parent":"6",
173                             "from_store":"",
174                             "app_type":"information",
175                             "lock_status":"0",
176                             "web_show":"1",
177                             "open_type":"1",
178                             "level":"3",
179                             "link":"/app/!/information/wenjuanjianchaxiang",
180                             "description":"",
181                             "icon_name":"qy-contact_list",
182                             "personalize":"0",
183                             "jump_addr":"",
184                             "icon_color":"#54698d",
185                             "children":[
186 
187                             ],
188                             "name":"问卷检查项",
189                             "id":"10",
190                             "app_id":"wenjuanjianchaxiang",
191                             "package_version_code":"",
192                             "showChildren":false,
193                             "order":"1"
194                         }
195                     ],
196                     "name":"检查问卷",
197                     "id":"6",
198                     "package_version_code":"",
199                     "showChildren":false,
200                     "order":"2"
201                 }
202             ],
203             "name":"开发者应用",
204             "id":"3",
205             "package_version_code":"",
206             "showChildren":false,
207             "order":"1"
208         },
209         {
210             "parent":"0",
211             "from_store":"",
212             "app_type":"",
213             "lock_status":"0",
214             "open_type":"1",
215             "level":"1",
216             "link":"",
217             "description":"",
218             "icon_name":"qy-channel_program_leve",
219             "personalize":"0",
220             "jump_addr":"",
221             "icon_color":"#fcb95b",
222             "children":[
223                 {
224                     "app_show":"1",
225                     "parent":"19",
226                     "from_store":"",
227                     "app_type":"information",
228                     "lock_status":"0",
229                     "web_show":"1",
230                     "open_type":"1",
231                     "level":"2",
232                     "link":"/app/!/information/chuanbojibenxinxi",
233                     "description":"",
234                     "icon_name":"qy-custom93",
235                     "personalize":"0",
236                     "jump_addr":"",
237                     "icon_color":"#54698d",
238                     "children":[
239 
240                     ],
241                     "name":"船舶基本信息",
242                     "id":"14",
243                     "app_id":"chuanbojibenxinxi",
244                     "package_version_code":"",
245                     "showChildren":false,
246                     "order":"0"
247                 },
248                 {
249                     "app_show":"1",
250                     "parent":"19",
251                     "from_store":"",
252                     "app_type":"information",
253                     "lock_status":"0",
254                     "web_show":"1",
255                     "open_type":"1",
256                     "level":"2",
257                     "link":"/app/!/information/qiyexinxi5",
258                     "description":"",
259                     "icon_name":"qy-channel_program_leve",
260                     "personalize":"0",
261                     "jump_addr":"",
262                     "icon_color":"#ef6e64",
263                     "children":[
264 
265                     ],
266                     "name":"企业信息",
267                     "id":"18",
268                     "app_id":"qiyexinxi5",
269                     "package_version_code":"",
270                     "showChildren":false,
271                     "order":"1"
272                 }
273             ],
274             "name":"船舶信息管理",
275             "id":"19",
276             "package_version_code":"",
277             "showChildren":false,
278             "order":"11"
279         },
280         {
281             "parent":"0",
282             "from_store":"",
283             "app_type":"",
284             "lock_status":"0",
285             "open_type":"1",
286             "level":"1",
287             "link":"",
288             "description":"",
289             "icon_name":"qy-answer_private",
290             "personalize":"0",
291             "jump_addr":"",
292             "icon_color":"#fa975c",
293             "children":[
294                 {
295                     "app_show":"1",
296                     "parent":"20",
297                     "from_store":"",
298                     "app_type":"information",
299                     "lock_status":"0",
300                     "web_show":"1",
301                     "open_type":"1",
302                     "level":"2",
303                     "link":"/app/!/information/pingjifufenjilu",
304                     "description":"",
305                     "icon_name":"qy-souyisou",
306                     "personalize":"0",
307                     "jump_addr":"",
308                     "icon_color":"#00cdc0",
309                     "children":[
310 
311                     ],
312                     "name":"评级赋分记录",
313                     "id":"12",
314                     "app_id":"pingjifufenjilu",
315                     "package_version_code":"",
316                     "showChildren":false,
317                     "order":"0"
318                 }
319             ],
320             "name":"评级赋分管理",
321             "id":"20",
322             "package_version_code":"",
323             "showChildren":false,
324             "order":"111"
325         },
326         {
327             "parent":"0",
328             "from_store":"",
329             "app_type":"",
330             "lock_status":"0",
331             "open_type":"1",
332             "level":"1",
333             "link":"",
334             "description":"",
335             "icon_name":"qy-custom43",
336             "personalize":"0",
337             "jump_addr":"",
338             "icon_color":"#a904ed",
339             "children":[
340                 {
341                     "app_show":"1",
342                     "parent":"21",
343                     "from_store":"",
344                     "app_type":"information",
345                     "lock_status":"0",
346                     "web_show":"1",
347                     "open_type":"1",
348                     "level":"2",
349                     "link":"/app/!/information/falvfaguixinxi",
350                     "description":"",
351                     "icon_name":"qy-environment_hub",
352                     "personalize":"0",
353                     "jump_addr":"",
354                     "icon_color":"#8199af",
355                     "children":[
356 
357                     ],
358                     "name":"法律法规信息",
359                     "id":"16",
360                     "app_id":"falvfaguixinxi",
361                     "package_version_code":"",
362                     "showChildren":false,
363                     "order":"0"
364                 },
365                 {
366                     "app_show":"1",
367                     "parent":"21",
368                     "from_store":"",
369                     "app_type":"information",
370                     "lock_status":"0",
371                     "web_show":"1",
372                     "open_type":"1",
373                     "level":"2",
374                     "link":"/app/!/information/zhuanjiakuxinxi",
375                     "description":"",
376                     "icon_name":"qy-contact_list",
377                     "personalize":"0",
378                     "jump_addr":"",
379                     "icon_color":"#fe8f60",
380                     "children":[
381 
382                     ],
383                     "name":"专家库信息",
384                     "id":"17",
385                     "app_id":"zhuanjiakuxinxi",
386                     "package_version_code":"",
387                     "showChildren":false,
388                     "order":"1"
389                 }
390             ],
391             "name":"系统资料库",
392             "id":"21",
393             "package_version_code":"",
394             "showChildren":false,
395             "order":"1111"
396         }
397     ],
398     "message":"获取数据成功",
399     "status":200
400 }
复制代码

最终效果如下:

总结:当遇到多叉树或无限层级问题时,vue的递归组件是个比较好的解决方案,可以较大的节约开发时间降低开发成本。

参考网站:

https://segmentfault.com/a/1190000020638864?utm_source=tag-newest

https://blog.csdn.net/goodsave/article/details/78879842

https://www.cnblogs.com/fei-H/p/11359028.html

漫思
原文地址:https://www.cnblogs.com/sexintercourse/p/13565147.html