先上效果图↓↓↓
目前我们要做的效果就是左边这一块
因为是基于elementUI的,所以需要先下载elementUI的依赖,老手可忽略
npm i element-ui -S
同时还需要用到vuex,用于控制头部标签与左边菜单栏的同步操作
安装vuex依赖
npm install vuex --save
如果你是小白,请先学会vuex的使用
目前的功能没有使用到vuex,后续功能会用到,所以目前vuex可以忽略↑↑↑
为了演示方便,我是把所有导航栏的文件放在一起的,可以不用和我一样
废话不多说,直接上代码
下面是子组件代码↓↓↓
TMenu.vue
<!-- TMenu.vue -->
<template>
<!-- 源码问题,需加上:popper-append-to-body="false",不然会导致重复调用 -->
<el-submenu v-if="menu.children && menu.children.length >= 1" :index="menu.menuId + ''" :key="menu.menuId" :popper-append-to-body="false">
<template slot="title">
<i :class="menu.icon"></i>
<span slot="title">{{menu.menuName}}</span>
</template>
<t-menu v-for="item in menu.children" :menu="item" :key="item.menuId"></t-menu>
</el-submenu>
<el-menu-item v-else :index="menu.menuId + ''" :key="menu.menuId">
<i :class="menu.icon"></i>
<span slot="title">{{menu.menuName}}</span>
</el-menu-item>
</template>
<script>
export default {
name: 'TMenu', //组件名
props: {
menu: {
type: Object,
required: true
}
}
}
</script>
<style scoped>
</style>
下面是使用方式的代码↓↓↓
NavBar.vue
<template>
<div class="menu-bar-container">
<!-- 组件使用方法 -->
<el-menu ref="navmenu" :default-active="activeIndex" :collapse="isCollapse"
:class="isCollapse?'el-menu-width2':'el-menu-width1'" :collapse-transition="false">
<t-menu v-for="item in menus" :menu="item" :key="item.menuId"></t-menu>
</el-menu>
</div>
</template>
<script>
import { mapState } from 'vuex';//此处可以不使用
import TMenu from './TMenu'
import {menuTreeData} from './menu';//导入数据,此处我的数据写死了,你可以是后台传过来的数据
export default {
computed: {
... mapState({
//用于控制折叠,类型为boolean,false为展开,我这里使用了vuex,你可以写在data中
isCollapse: state=>state.menu.isCollapse,
activeIndex: state=>state.menu.activeIndex
})
},
components:{
TMenu
},
data() {
return {
//isCollapse:false,//可以写在这里
menus:menuTreeData
};
}
}
</script>
<style>
.menu-bar-container {
position: fixed;
top: 0px;
left: 0;
bottom: 0;
z-index: 1020;
}
.el-menu-width1{
width: 200px;
}
.el-menu-width2{
width: 65px;
}
</style>
下面是数据格式的代码↓↓↓
menu.js
/**
* 权限管理在后台,前端接收到的是已经过滤完的菜单树
* @menuId 菜单唯一识别
* @menuName 名称
* @icon 图标
* @parentId 父菜单,前端不用,后端用来嵌套树
* @route 只有叶子结点有路由
* @type 是菜单级别,只有一级菜单和二级菜单
* @orderNum 是菜单排序,后台需要用来排序,前端不用
* @children 叶子结点没有该属性或者为空数组
*/
// 获取菜单树
export const menuTreeData = [{
"menuId": 1,
"menuName": "系统管理",
"parentId": 0,
"route": null,
"type": 0,
"icon": "el-icon-setting",
"orderNum": 0,
"children": [{
"menuId": 11,
"menuName": "权限管理",
"parentId": 1,
"parentName": "系统管理",
"route": "../views/new1",
"type": 1,
"icon": "el-icon-warning-outline",
"orderNum": 1,
"children": []
},
{
"menuId": 12,
"menuName": "菜单管理",
"parentId": 1,
"parentName": "系统管理",
"route": "../views/new2",
"type": 1,
"icon": "el-icon-menu",
"orderNum": 2,
"children": []
}
]
},
{
"menuId": 2,
"menuName": "个人管理",
"parentId": 0,
"route": null,
"type": 0,
"icon": "el-icon-user",
"orderNum": 2,
"children": [
{
"menuId": 21,
"menuName": "密码管理",
"parentId": 4,
"parentName": "个人管理",
"route": null,
"type": 1,
"icon": "el-icon-view",
"orderNum": 1,
"children": [
{
"menuId": 211,
"menuName": "密保管理",
"parentId": 5,
"parentName": "密码管理",
"route": "../views/new3",
"type": 2,
"icon": "el-icon-link",
"orderNum": 1,
"children": []
}]
},
{
"menuId": 22,
"menuName": "历史记录",
"parentId": 5,
"parentName": "个人管理",
"route": "../views/new1",
"type": 1,
"icon": "el-icon-zoom-in",
"orderNum": 1,
"children": []
}]
}]
好了,功能完成,大致效果为下图,可能样式会有所区别,可以自己进行调整