如何用递归写element-ui的导航菜单
1.准备数据:
在main.vue组件准备好数据
data(){
return{
isCollapse: false,
menuList:{
"code": 200,
"message": "操作成功",
"data": [
{
"createdBy": null,
"createdDate": null,
"updatedBy": null,
"updatedDate": null,
"id": "1",
"name": "首页",
"url": "common/home",
"type": 1,
"parentId": 0,
"parentName": null,
"icon": "credits",
"orderNum": 0,
"children": null
},
{
"createdBy": null,
"createdDate": null,
"updatedBy": null,
"updatedDate": null,
"id": "5",
"name": "待办管理",
"url": "",
"type": 0,
"parentId": 0,
"parentName": null,
"icon": "email",
"orderNum": 1,
"children": [
{
"createdBy": null,
"createdDate": null,
"updatedBy": null,
"updatedDate": null,
"id": "6",
"name": "待办文件",
"url": "pend/waitinfo",
"type": 1,
"parentId": 5,
"parentName": "待办管理",
"icon": "lock",
"orderNum": 0,
"children": null
},
{
"createdBy": null,
"createdDate": null,
"updatedBy": null,
"updatedDate": null,
"id": "7",
"name": "办文跟踪",
"url": "pend/fllowinfo",
"type": 1,
"parentId": 5,
"parentName": "待办管理",
"icon": "time",
"orderNum": 1,
"children": null
}]}]}
}
2.在mian.vue组件引入menuSun组件,并且将这个数据传过去
<div class="aside">
<div class="titleWrapper">
<div class="titleWrap">
<svg-icon icon-class="logo" class="logo"></svg-icon>
<transition name="slide-fade">
<span class="logoTitle" v-if="!isCollapse">信息管理系统</span>
</transition>
</div>
</div>
<el-menu default-active="1" unique-opened class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose" :collapse="isCollapse" background-color="#545c64" text-color="#fff" active-text-color="#ffd04b">
<menuSun :menuList="menuList.data" :isCollapse="isCollapse"></menuSun>
</el-menu>
</div>
注意:这里最外面一层不能封装进去,因为后面封装进去的都要递归。
css:
.aside{
height: 100%;
background: rgb(84, 92, 100);
.el-menu{
border: rgb(84, 92, 100);
}
.el-menu-vertical-demo:not(.el-menu--collapse) {
width: 200px;
ul{
width: 200px;
}
}
.titleWrapper{
height: 60px;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
.logo{
font: 20px/60px '微软雅黑';
}
.logoTitle{
color: #fff;
}
/* 可以设置不同的进入和离开动画 */
/* 设置持续时间和动画函数 */
.slide-fade-enter-active {
transition: all 2s ease;
}
.slide-fade-leave-active {
transition: all .2s cubic-bezier(1.0, 0.5, 0.8, 1.0);
}
.slide-fade-enter, .slide-fade-leave-to {
transform: translateX(10px);
opacity: 0;
}
}
}
3.在menuSun组件中
html:
<template>
<div class="menuSun">
<template v-for="(item) in menuList">
<el-submenu v-if="item.children&&item.children.length>0" :key="item.id" :index="item.id">
<template slot="title">
<svg-icon :icon-class="item.icon"></svg-icon>
<span slot="title">{
{item.name}}</span>
</template>
<menuSun :menuList="item.children" :collapse="isCollapse2"></menuSun>
</el-submenu>
<el-menu-item v-else :key="item.id" :index="item.id">
<svg-icon :icon-class="item.icon"></svg-icon>
<span slot="title">{
{item.name}}</span>
</el-menu-item>
</template>
</div>
</template>
js:
<script>
import menuSun from '@/components/menuSun'
export default {
name: 'menuSun',
props:{
menuList:{
type:Array,
required:true
},
isCollapse:{
type:Boolean,
required:false
}
},
components:{
menuSun
},
data(){
return{
isCollapse2:false
}
},
methods:{
handleOpen(key, keyPath) {
console.log(key, keyPath);
},
handleClose(key, keyPath) {
console.log(key, keyPath);
}
},
created(){
}
}
</script>
css:
<style lang="less">
.menuSun {
height: 100%;
.el-menu{
border: rgb(84, 92, 100);
}
.el-submenu{
min-width: auto!important;
}
.el-menu-vertical-demo:not(.el-menu--collapse) {
width: 200px;
}
}
</style>
效果:
默认展开:
点击图标就折叠:
这里需要注意几点:
1)svg图标尚不能添加click事件
2)这里的页面布局是用flex布局,而不是之前的calc布局,因为左边的宽度是不确定的。