element ui动态侧边菜单栏及页面布局实现方法

 更新时间:2023年09月17日 10:11:49   作者:薇森  
后台管理系统经常会使用到一个左侧菜单栏,右侧Tab页的页面显示结构,这篇文章主要给大家介绍了关于element ui动态侧边菜单栏及页面布局实现的相关资料,需要的朋友可以参考下

一、实现效果

这里以学生成绩管理系统为例,整体布局以及实现效果如下所示:

94694b04f5da47ca9a61053ff4610835.gif

二、整体布局 

整体布局采用elementui 中Container 布局容器组件实现,如下所示。

2eafe6f26c474013958eaa90406c8c26.jpeg

整个页面布局页面为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数组:

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) {
      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动态侧边菜单栏及页面布局实现的文章就介绍到这了,更多相关element ui动态侧边菜单栏内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:

相关文章

  • vue-cli脚手架引入弹出层layer插件的几种方法

    vue-cli脚手架引入弹出层layer插件的几种方法

    layer.js(mobile)是一个小巧方便的弹出层插件,在之前的apicloud项目中被大量使用,但最近对apicloud的IDE、非常不友好的文档和极低的开发效率深感厌烦,决定弃用然后转向Vue开发。这篇文章主要介绍了vue-cli脚手架引入弹出层layer插件的几种方法,需要的朋友可以参考下
    2019-06-06
  • Vue3中Provide / Inject的实现原理分享

    Vue3中Provide / Inject的实现原理分享

    provide和inject主要为高阶插件/组件库提供用例,这篇文章主要给大家介绍了关于Vue3中Provide / Inject的实现原理,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-02-02
  • Vue Element前端应用开发之动态菜单和路由的关联处理

    Vue Element前端应用开发之动态菜单和路由的关联处理

    这篇文章主要介绍了Vue Element前端应用开发之动态菜单和路由的关联处理,对vue感兴趣的同学,可以参考下
    2021-05-05
  • vue使用file-saver插件保存各种格式文件方式

    vue使用file-saver插件保存各种格式文件方式

    这篇文章主要介绍了vue使用file-saver插件保存各种格式文件方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-07-07
  • 如何搭建一个完整的Vue3.0+ts的项目步骤

    如何搭建一个完整的Vue3.0+ts的项目步骤

    这篇文章主要介绍了如何搭建一个完整的Vue3.0+ts的项目步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-10-10
  • 解决在el-dialog中无法正确获取DOM的问题

    解决在el-dialog中无法正确获取DOM的问题

    这篇文章主要介绍了解决在el-dialog中无法正确获取DOM的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • Vue3项目中reset.scss模板使用导入

    Vue3项目中reset.scss模板使用导入

    这篇文章主要为大家介绍了Vue3项目中reset.scss模板使用导入示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • vue点击导航页面实现自动滚动到特定位置

    vue点击导航页面实现自动滚动到特定位置

    这篇文章主要介绍了vue点击导航页面实现自动滚动到特定位置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • el-select单选时选择后输入框的is-focus状态并没有取消问题解决

    el-select单选时选择后输入框的is-focus状态并没有取消问题解决

    这篇文章主要给大家介绍了关于el-select单选时选择后输入框的is-focus状态并没有取消问题的解决过程,文中通过图文以及代码示例将解决的办法介绍的非常详细,需要的朋友可以参考下
    2024-01-01
  • 一次用vue3简单封装table组件的实战过程

    一次用vue3简单封装table组件的实战过程

    之所以封装全局组件是为了省事,所有的目的,全都是为了偷懒,下面这篇文章主要给大家介绍了关于用vue3简单封装table组件的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2022-12-12

最新评论