菜单实现是用 elementui 的 el-menu 来实现的,因为我们是动态展示菜单的,所以这里需要对 el-menu 进行一个封装。
MenuTree.vue 组件封装:
<template> <div> <template v-for="(item, index) in this.menuData"> <!-- 情况一:有子集的情况 --> <el-submenu :key="index" :index="String(index + 1)" v-if="item.children && item.children.length > 0"> <template slot="title"> <i : style="color: #000"></i> <span slot="title" style="margin-left: 9px">{{item.menuName}}</span> </template> <left-menu-tree :menuData="item.children"></left-menu-tree> </el-submenu> <!-- 情况二:没子集的情况 --> <el-menu-item :key="index" v-else-if="item.menuStatus && item.menuStatus == 1" :index="String(index + 1)"> <i : style="color: #000"></i> <span slot="title" style="margin-left: 9px">{{item.menuName}}</span> </el-menu-item> </template> </div> </template> <script> import { OPENTYPE } from "@/config/constant"; export default { props: ['menuData'], name: 'LeftMenuTree', } </script>
在页面中使用:
<div > <el-menu active-text-color="#303133" text-color="#606266" @open="handleOpen" @close="handleClose" > <menu-tree :menuData="menuList"></menu-tree> </el-menu> </div>
这里后端返回的数据是否展示,是通过 menuStatus 字段来判断的,0 为隐藏菜单,1 为展示菜单。模拟数据如下:
const menuList= [ { menuName: '菜单一', menuStatus: 1, children: [ { menuName: 'ww', menuStatus: 0, }, { menuName: 'rr', menuStatus: 1, children: [ { menuName: 'tt', status: 1, children: [ { menuName: 'ooo', menuStatus: 0, }, { menuName: 'pp', menuStatus: 1, children: [ { menuName: 'ooo', menuStatus: 0, }, { menuName: 'pp', menuStatus: 0, }, ] }, ] }, { menuName: 'rr', menuStatus: 0, }, ] }, ] }, { menuName: '菜单二', menuStatus: 1, children: [ { menuName: 'bb', menuStatus: 0, }, { menuName: 'we', menuStatus: 0, }, ] }, { menuName: '菜单三', menuStatus: 1, } ]
这里我们就需要通过一个一个过滤方法来过滤掉 menuStatus 为 0 的数据,显示状态为 1 的,过滤方法如下:
function filterMenuData(menuData) { return menuData .filter(item => item.menuStatus === 1) .map(item => { if (item.children) { return { ...item, children: filterMenuData(item.children) }; } else { return item; } }); } this.menuList = filterMenuData(this.menuList);
至此,完美展示出我们的菜单,举一反三,特此记录。