基于ElementUI的项目,由于原本的navbar是写死的,所以自己封装菜单组件,让他能够不限子菜单层级渲染
目录:
- 数据结构
menuList: [
{
id: 0,
type: "item",
index: "home",
lable: "首页",
icon: "el-icon-circle-plus-outline",
route: {
type: "inner",
path: { name: "GainIframe", params: { id: "2" } }
}
},
{
id: 1,
type: "submenu",
index: "news",
lable: "系统管理",
icon: "el-icon-circle-plus-outline",
childs: [
{
id: 2,
type: "item",
index: "addMenu",
lable: "菜单管理",
icon: "el-icon-circle-plus-outline",
route: {
type: "inner",
path: { name: "AddNews" }
}
},
{
id: 3,
type: "submenu",
index: "rolesList",
lable: "角色管理",
icon: "el-icon-circle-plus-outline",
route: {
type: "inner",
path: { name: "GainIframe", params: { id: "2" } }
},
childs: [
{
id: 4,
type: "item",
index: "submenu",
lable: "用户管理",
icon: "el-icon-circle-plus-outline",
route: {
type: "inner",
path: { name: "GainIframe", params: { id: "2" } }
}
}
]
}
]
},
{
id: 5,
type: "submenu",
index: "news",
lable: "新闻",
icon: "el-icon-circle-plus-outline",
childs: [
{
id: 6,
type: "item",
index: "addNews",
lable: "发布新闻",
icon: "el-icon-circle-plus-outline",
route: {
type: "inner",
path: { name: "AddNews" }
}
},
{
id: 7,
type: "submenu",
index: "newsList",
lable: "新闻列表",
icon: "el-icon-circle-plus-outline",
route: {
type: "inner",
path: { name: "NewsList" }
},
childs: [
{
id: 8,
type: "submenu",
index: "NewsAdd",
lable: "新闻添加",
icon: "el-icon-circle-plus-outline",
route: {
type: "inner",
path: { name: "NewsList" }
},
childs: [
{
id: 9,
type: "submenu",
index: "addNews",
lable: "发布新闻",
icon: "el-icon-circle-plus-outline",
route: {
type: "inner",
path: { name: "AddNews" }
},
childs: [
{
id: 10,
type: "item",
index: "NewsPush",
lable: "新闻发布",
icon: "el-icon-circle-plus-outline",
route: {
type: "inner",
path: { name: "AddNews" }
}
}
]
}
]
}
]
}
]
}
]
- MenuGroup.vue
<template>
<el-menu-item-group>
<template slot="title" v-if="menu.lable!== null">
<i :class="menu.icon"></i>
<span slot="title">{{ menu.lable }}</span>
</template>
<template v-if="menu.childs!== null">
<template v-for="menuItem in menu.childs">
<template v-if="menuItem.type === 'item'">
<menu-item :menu="menuItem" :key="menuItem.id"></menu-item>
</template>
<template v-if="menuItem.type === 'submenu'">
<sub-menu :menu="menuItem" :key="menuItem.id"></sub-menu>
</template>
</template>
</template>
</el-menu-item-group>
</template>
<script>
import MenuItem from './MenuItem.vue'
import SubMenu from './subMenu.vue'
export default {
name:'MenuGroup',
props: {
menu: {
type: Object
}
},
components: {MenuItem,SubMenu},
data () {
return {
}
}
}
</script>
<style>
</style>
- subMenu.vue
<template>
<el-submenu v-if="menu.type === 'submenu'" :index="menu.index">
<template slot="title" v-if="menu.lable !== null">
<i :class="menu.icon"></i>
<span slot="title">{{ menu.lable }}</span>
</template>
<template v-if="menu.childs !== null">
<template v-for="menuItem in menu.childs">
<template v-if="menuItem.type === 'item'">
<menu-item :menu="menuItem" :key="menuItem.id"></menu-item>
</template>
<template v-if="menuItem.type === 'submenu'">
<sub-menu :menu="menuItem" :key="menuItem.id"></sub-menu>
</template>
<template v-if="menuItem.type === 'group'">
<menu-group :menu="menuItem" :key="menuItem.id"></menu-group>
</template>
</template>
</template>
</el-submenu>
</template>
<script>
import MenuItem from "./MenuItem.vue";
import MenuGroup from "./MenuGroup.vue";
export default {
name: "subMenu",
props: {
menu: {
type: Object
}
},
components: { MenuItem, MenuGroup },
data() {
return {};
}
};
</script>
<style>
</style>
- MenuItem.vue
<template>
<el-menu-item :index="menu.index" :route="menu.route.path">
<template>
<i :class="menu.icon"></i><span slot="title">{{ menu.lable}}</span>
</template>
</el-menu-item>
</template>
<script>
export default {
name:'MenuItem',
props:{
menu:{
type:Object
}
},
data(){
return {}
}
}
</script>
<style>
</style>
- Menu.vue
<template>
<div>
<!-- <el-radio-group v-model="isCollapse">
<el-radio-button :label="false">展开</el-radio-button>
<el-radio-button :label="true">收起</el-radio-button>
</el-radio-group> -->
<el-menu
default-active="1-3-1"
class="el-menu-vertical-demo"
@open="handleOpen"
@close="handleClose"
:collapse="isCollapse"
:background-color="menuSetting.backgroundColor"
:text-color="menuSetting.textColor"
:active-text-color="menuSetting.activeTextColor"
:unique-opened="menuSetting.uniqueOpened"
:router="menuSetting.router"
>
<template v-for="menuItem in menuList">
<template v-if="menuItem.type === 'item'">
<menu-item :menu="menuItem" :key="menuItem.id"></menu-item>
</template>
<template v-if="menuItem.type === 'submenu'">
<sub-menu :menu="menuItem" :key="menuItem.id"></sub-menu>
</template>
<template v-if="menuItem.type === 'group'">
<menu-group :menu="menuItem" :key="menuItem.id"></menu-group>
</template>
</template>
</el-menu>
</div>
</template>
<script>
import MenuItem from "./subcomponents/MenuItem.vue";
import SubMenu from "./subcomponents/subMenu.vue";
import MenuGroup from "./subcomponents/MenuGroup.vue";
export default {
components: { MenuItem, SubMenu, MenuGroup },
data() {
return {
isCollapse: false, //菜单切换
menuSetting: {
backgroundColor: "#842D7D",
textColor: "#fff",
activeTextColor: "#ffd04b",
defaultOpeneds: [],
uniqueOpened: true,
router: true, //直接使用 index 进行路由跳转
collapseTransition: true
},
menuList: [
{
id: 0,
type: "item",
index: "home",
lable: "首页",
icon: "el-icon-circle-plus-outline",
route: {
type: "inner",
path: { name: "GainIframe", params: { id: "2" } }
}
},
{
id: 1,
type: "submenu",
index: "news",
lable: "系统管理",
icon: "el-icon-circle-plus-outline",
childs: [
{
id: 2,
type: "item",
index: "addMenu",
lable: "菜单管理",
icon: "el-icon-circle-plus-outline",
route: {
type: "inner",
path: { name: "AddNews" }
}
},
{
id: 3,
type: "submenu",
index: "rolesList",
lable: "角色管理",
icon: "el-icon-circle-plus-outline",
route: {
type: "inner",
path: { name: "GainIframe", params: { id: "2" } }
},
childs: [
{
id: 4,
type: "item",
index: "submenu",
lable: "用户管理",
icon: "el-icon-circle-plus-outline",
route: {
type: "inner",
path: { name: "GainIframe", params: { id: "2" } }
}
}
]
}
]
}
]
};
},
methods: {
handleOpen(key, keyPath) {
console.log(key, keyPath);
},
handleClose(key, keyPath) {
console.log(key, keyPath);
}
}
};
</script>
<style>
.el-menu-vertical-demo:not(.el-menu--collapse) {
width: 200px;
min-height: 880px;
}
</style>
- 效果:
参考链接: