这里以学生成绩管理系统为例,整体布局以及实现效果如下所示:
整体布局采用elementui中Container布局容器组件实现,如下所示。
整个页面布局页面为main.vue,其中左侧菜单栏部分被封装为一个组件(MenuTree),菜单部分使用elementui中Menu菜单组件来实现,其中el-menu当中参数unique-opened为只允许一个展开,参数default-active为默认激活菜单的index,参数router为在激活导航时以index作为path进行路由跳转,具体代码如下:
组件为menustree.vue,在上面的布局main.vue中导入,动态菜单数据menuList(json数组格式)从父组件main.vue传递到该页面,再循环递归实现。注意数据中parentid为0的数据表示为根路径,即最外层,icon为图标,也是使用elementui当中的图标组件,url为跳转路由。具体代码如下所示:
这是使用嵌套路由,将菜单栏各个页面嵌套在main页面右侧展示,重定向是为了让初始右侧页面显示系统主页,具体配置如下所示:
constroutes=[//整体布局页面{path:'/main',name:'main',component:()=>import("@/views/main"),//重定向,自动跳转到指定路由redirect:"/homepage",//嵌套路由children:[{path:'/homepage',name:'系统主页',component:()=>import("@/views/homepage"),},{path:'/grade',name:'成绩管理',component:()=>import("@/views/grade"),},{path:'/information',name:'信息管理',component:()=>import("@/views/information"),},{path:'/password',name:'密码修改',component:()=>import("@/views/password"),},{path:'/course',name:'课程管理',component:()=>import("@/views/course"),}]},]
菜单栏数据menuList为嵌套的json数据格式,在实际开发中,menuList需要从后端构造成嵌套json数组的格式,传递到前端来进行动态数据展示,格式如下:
menuList:[{id:1,parentid:'0',name:'系统主页',icon:'HomeFilled',url:'/homepage',},{id:2,parentid:'0',name:'学生管理',icon:'UserFilled',children:[{id:3,parentid:'2',name:'信息管理',icon:'',children:[{id:4,parentid:'2',name:'密码修改',icon:'',url:'/password'}]},{id:5,parentid:'2',name:'成绩管理',icon:'',url:'/grade',}]},{id:6,parentid:'0',name:'课程管理',icon:'List',url:'/course',}],此外,后端也可以传递过来,如下格式的json数组:
menuList=[{id:1,parentid:'0',name:'系统主页',icon:'HomeFilled',url:'/homepage',},{id:2,parentid:'0',name:'学生管理',icon:'UserFilled',url:'',},{id:3,parentid:'2',name:'信息管理',icon:'',url:'',}];但是此时需要在前端对其进行构造,变成上面的嵌套的形式才能供菜单栏组件使用,调用以下方法可将上面的数据变为json嵌套数组,(注意,id,name等可以自己命名,对应修改即可)构造的js方法如下:
/***@FileDescription:后台获取的菜单列表数据转为无限分类递归树,嵌套JSON数据格式*/totree(data){letmap={};letval=[];//生成数据对象集合data.forEach(it=>{map[it.id]=it;})//生成结果集data.forEach(it=>{constparent=map[it.parentid];if(parent){if(!Array.isArray(parent.children))parent.children=[];parent.children.push(it);}else{val.push(it);}})returnval;},