场景:因项目需要一个动态的侧边栏,不能自己写死element-ui中的导航菜单
思路:结合vue中的递归组件实现,直接上代码吧
父组件的侧边栏
<el-menu
router
class="el-menu-vertical-demo"
background-color="#545c64"
text-color="#fff"
active-text-color="#ffd04b"
>
<Menu
v-for="(item, index) in routerList"
:key="index"
:item="item"
:path="item.path"
></Menu>
</el-menu>
// Menu是引入的组件
routerList: [
{
name: "导航一",
path: "1",
children: [
{
name: "1-1",
path: "1-1",
children: [
{
name: "1-1-1",
path: "1-1-1",
children: [
{
name: "1-1-1-1",
path: "1-1-1-1",
children: []
}
]
}
]
},
{
name: "1-2",
path: "1-2",
children: []
}
]
},
{
name: "导航二",
path: "2",
children: [
{
name: "2-1",
path: "2-1",
children: [
{
name: "2-1-1",
path: "2-1-1",
children: []
}
]
}
]
}
],
递归的子组件
// Menu组件
<el-menu-item :index="item.path" v-if="item.children.length <= 0">
<i class="el-icon-setting"></i>
<span slot="title">{{ item.name }}</span>
</el-menu-item>
<el-submenu :index="item.path" v-else>
<template slot="title">
<i class="el-icon-location"></i>
<span>{{ item.name }}</span>
</template>
<Menu
v-for="child in item.children"
:key="child.path"
:item="child"
:path="child.path"
></Menu>
</el-submenu>
<script>
export default {
name: "Menu",
props: {
item: {
type: Object,
required: true
},
path: {
type: String,
default: ""
}
}
};
</script>
因为是动态设置的侧边栏,所有routerList格式必须是一个数组。在父组件中传入list和固定的路径,而在子组件中需要根据当前接受的list中的每一项的children的length来判断是否有子项。 当children的length为0时代表当前的是el-menu-item(需要点击展示内容),当children的length不为0时则代表是el-submenu(点击可展开子项). 然后在el-submenu中可以继续传入当前的组件(Menu组件),并且传入对应的每一个children用于遍历。这样形成了递归组件。
注意:这里有两个坑: 1.子组件中因为需要递归,所有必须要有name属性,因为vue中规定,要实现递归组件的话,需要根据name来识别递归的组件。 2.因为是递归组件,所以必须要有一个'出口',这里就是根据children的length来判断的