一、思路
利用组件递归思想
二、代码实现
index文件
<template>
<div class="side-menu-wrapper">
<el-aside width="100%">
<el-menu :default-openeds="defaultOpends" :default-active="defaultActive">
<template v-for="(item, index) in sideDate">
<template v-if="item.children && item.children.length">
<SideMenuItem :key="index" :list="item.children" :index="String(index)" :sub-label="item.label"/>
</template>
<template v-else>
<el-menu-item :index="String(index)" :key="index" @click="handleClick(item)">
<i class="el-icon-setting"></i>
<span slot="title">{
{
item.label }}</span>
</el-menu-item>
</template>
</template>
</el-menu>
</el-aside>
</div>
</template>
<script>
import SideMenuItem from './sideMenuItem'
export default {
name: 'index',
components: {
SideMenuItem
},
props: {
sideDate: {
// 渲染的数据
type: Array
},
defaultOpends: {
// 默认展开的项
type: Array
},
defaultActive: {
// 默认激活的菜单项
type: String,
default: '0-0'
}
},
methods: {
handleClick(item) {
if (item.name === this.$route.name) {
return
}
this.$router.push({
name: item.name
})
}
}
}
</script>
<style lang="scss" scoped>
@import "../../style/mixin";
.side-menu-wrapper {
width: 100%;
height: 100%;
/deep/ .el-aside {
height: 100%;
border-radius: 10px;
border: 1px solid $bgColor;
& > ul {
width: 100%;
height: 100%;
border-radius: 10px;
border: 1px solid $bgColor;
.el-submenu__title {
font-size: 18px;
color: $fontColor;
}
.el-menu-item {
font-size: 18px;
color: $fontColor;
}
.is-active {
color: #1890ff;
//background-color: #bae7ff;
}
.el-submenu__icon-arrow {
font-size: 16px;
color: $fontColor;
}
}
}
}
</style>
menuItem组件
<template>
<el-submenu :index="index">
<template slot="title"><i class="el-icon-message"></i>{
{
subLabel }}</template>
<template v-for="(subItem, subIndex) in list">
<template v-if=" subItem.children && subItem.children.length">
<!-- 组件自身递归调用 -->
<sideMenuItem :index="`${index}-${subIndex}`" :key="`${index}-${subIndex}`" :list="subItem.children" :sub-label="subItem.label"/>
</template>
<template v-else>
<el-menu-item :index="`${index}-${subIndex}`" :key="`${index}-${subIndex}`" @click="handleClick(subItem)">
<i class="el-icon-setting"></i>
<span slot="title">{
{
subItem.label }}</span>
</el-menu-item>
</template>
</template>
</el-submenu>
</template>
<script>
export default {
name: 'sideMenuItem',
props: {
list: {
type: Array,
default: () => []
},
index: String,
subLabel: String
},
methods: {
handleClick(item) {
if (item.name === this.$route.name) {
return
}
this.$router.push({
name: item.name
})
}
}
}
</script>
<style lang="scss" scoped>
/deep/ .el-menu-item {
font-size: 16px;
}
</style>
三、使用
<template>
<div>
<SideMenu :sideDate="list" :defaultOpends="['0']"/>
</div>
</template>
<script>
import SideMenu from '@/components/sideMenu'
export default {
components: {
SideMenu
},
data() {
return {
list: [
{
label: '海水水质',
name: 'test1',
icon: '',
path: 'test1',
children: [
{
label: '全国总体情况1',
name: '',
icon: '',
path: '',
children: [
{
label: '测试',
name: '',
icon: '',
path: '',
children: [
{
label: '测试',
name: '',
icon: '',
path: ''
}
]
}
]
},
{
label: '全国总体情况2',
name: '',
icon: '',
path: '',
children: [
{
label: '测试',
name: '',
icon: '',
path: ''
}
]
}
]
},
{
label: '海水水质',
name: 'test1',
icon: '',
path: 'test1',
children: [
{
label: '全国总体情况3',
name: '',
icon: '',
path: '',
children: [
{
label: '测试',
name: '',
icon: '',
path: ''
}
]
},
{
label: '全国总体情况4',
name: '',
icon: '',
path: '',
children: [
{
label: '测试',
name: '',
icon: '',
path: ''
}
]
}
]
},
{
label: '入海河流',
name: 'test1',
icon: '',
path: 'test1'
}
]
};
}
};
</script>
<style lang="scss" scoped>
@import "../style/mixin.scss";
.content {
@include content();
}
</style>
效果