一、实现效果
这里以学生成绩管理系统为例,整体布局以及实现效果如下所示:
二、整体布局
整体布局采用elementui 中Container 布局容器组件实现,如下所示。
整个页面布局页面为main.vue,其中左侧菜单栏部分被封装为一个组件( MenuTree),菜单部分使用elementui 中Menu 菜单组件来实现,其中el-menu当中参数unique-opened为只允许一个展开,参数default-active为默认激活菜单的 index,参数router为在激活导航时以 index 作为 path 进行路由跳转,具体代码如下:
<template>
<!-- 系统整体页面布局 -->
<el-container class="el-container">
<!-- 页面头部区域 高度默认60px -->
<el-header class="el-header">
<!-- 应用名称 -->
<span>学生成绩管理系统</span>
</el-header>
<el-container>
<!-- 左侧菜单栏部分 -->
<el-aside class="el-aside">
<el-scrollbar>
<el-menu class="el-menu"
background-color="#32323a"
:unique-opened="true"
:default-active="$route.path"
text-color="#ffffff"
router>
<MenuTree :menuList="menuList"></MenuTree>
</el-menu>
</el-scrollbar>
</el-aside>
<!-- 右侧主题页面内容展示 -->
<el-main class="el-mian">
<!-- 路由页面 -->
<router-view></router-view>
</el-main>
</el-container>
</el-container>
</template>
<script>
import MenuTree from '@/components/menu/menustree.vue';
export default {
components: {
MenuTree
},
data() {
return {
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',
}
],
}
},
}
</script>
<style>
/*铺满屏幕,没有边距*/
.el-container {
padding: 0px;
margin: 0px;
height: 100wh;
}
.el-header {
/* 顶部部分的高度(默认60px) */
background-color: #0077d5;
color: #FFFFFF;
font-size: 20px;
display: flex;
justify-content: space-between;
align-items: center;
height: 60px;
}
.el-aside {
width: 200px;
background-color: #32323a;
min-height: calc(100vh - 60px);
}
.el-menu {
width: 200px;
min-height:100%;
}
.el-menu span {
margin-left: 10px;
}
.el-mian {
background-color: #eaedf1;
padding: 0px;
margin: 0px;
height:calc(100vh - 60px);
}
</style>
三、菜单栏组件
组件为menustree.vue,在上面的布局main.vue中导入,动态菜单数据 menuList(json数组格式)从父组件main.vue传递到该页面,再循环递归实现。注意数据中parentid为0的数据表示为根路径,即最外层,icon为图标,也是使用elementui当中的图标组件,url为跳转路由。具体代码如下所示:
<template>
<div>
<template v-for="(item) in menuList">
<!-- 有次级菜单的,则展开子选项-->
<el-sub-menu v-if="item.children && item.children.length>0" :key="item.id" :index="item.id">
<template #title>
<el-icon v-if="item.icon!=''"><component :is="item.icon" /></el-icon>
<span :class="[item.parentid==0 ?'activespan':'disactivesapn']">{{item.name}}</span>
</template>
<!-- 递归,实现无限级展开 -->
<MenuTree :menuList="item.children"></MenuTree>
</el-sub-menu>
<!-- 没有次级菜单的 -->
<el-menu-item v-if="!item.children" :key="item.id" :index="item.url">
<el-icon v-if="item.icon!=''"><component :is="item.icon" /></el-icon>
<span :class="[item.parentid==0 ?'activespan':'disactivesapn']">{{item.name}}</span>
</el-menu-item>
</template>
</div>
</template>
<script>
import {
HomeFilled,
UserFilled,
List
} from "@element-plus/icons";
export default {
props:{
menuList:{
type:Array,
default(){
return []
}
}
},
name: 'MenuTree',
components: {
HomeFilled,
UserFilled,
List
},
methods: {
}
}
</script>
<style scoped>
.activespan{
font-size: 15px !important;
}
.disactivesapn{
margin-left: 20px;
font-size: 15px !important;
}
/* 菜单栏选中后背景色 */
.el-menu-item {
color: #ffffff;
}
.el-menu-item.is-active {
color: #55aaff;
}
</style>
四、路由部分
这是使用嵌套路由,将菜单栏各个页面嵌套在main页面右侧展示,重定向是为了让初始右侧页面显示系统主页,具体配置如下所示:
const routes = [
// 整体布局页面
{
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数组:文章来源:https://www.toymoban.com/news/detail-508202.html
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方法如下:文章来源地址https://www.toymoban.com/news/detail-508202.html
/**
* @FileDescription: 后台获取的菜单列表数据转为无限分类递归树,嵌套JSON数据格式
*/
totree(data) {
let map = {};
let val = [];
//生成数据对象集合
data.forEach(it => {
map[it.id] = it;
})
//生成结果集
data.forEach(it => {
const parent = map[it.parentid];
if (parent) {
if (!Array.isArray(parent.children)) parent.children = [];
parent.children.push(it);
} else {
val.push(it);
}
})
return val;
},
到了这里,关于element ui实现动态侧边菜单栏以及页面布局的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!