实现不限层级的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
漫思