最近在开发中遇见了一些问题,就是如何让多级菜单根据路由来实现动态显示。 最开始的想法是使用render函数,但是,render函数中有许多的问题,无法完美的契合elementUI来实现菜单的动态显示,许多属性无法使用,所以导致我不得不另想办法。 作为一个刚入行一年的前端菜鸟,由于从来没有做过这种需求,所以一筹莫展,还是请教了同事才找到了解决办法。
这是父组件代码
<template>
<div class="sidbar-container">
<el-menu
class="el-menu-vertical-demo"
:class="{'el-menu-two': isCollapse,'el-menu-one':!isCollapse}"
:collapse="isCollapse"
background-color="rgba(107, 107, 107, 0.836)"
text-color="rgb(238, 238, 238)"
active-text-color="#ffd04b"
:collapse-transition="true"
>
<Menu :libraryMenu="menuRoutes" @clickLibrary="clickLibrary" :isCollapse="isCollapse"></Menu>
</el-menu>
</div>
</template>
<script>
import Menu from '@/Layout/sidbar/itemTest.vue'
export default {
data() {
return {
menuRoutes: []
}
},
components: {
Menu
},
computed: {
isCollapse() {
return this.$store.getters['isCollapse']
}
},
created() {
// console.log(this.$router)
this.menuRoutes = this.$router.options.routes.filter(it=>{
return it.routeName == 'Layout'
})
// console.log(this.menuRoutes)
},
methods:{
clickLibrary(obj) {
// console.log(obj)
this.$router.push(obj.path)
}
}
};
</script>
在父组件中我先是获取到项目中的路由。然后通过筛选,把菜单路由遍历出来传递给封装好的子组件。同时传递给子组件的还有导航的点击方法。
子组件
<template>
<div>
<template v-for="item in libraryMenu">
<el-submenu
:index="item.path"
v-if="(item.children)"
:key="item.path"
>
<template slot="title">
<i class="iconfont" :class="item.icon"></i>
<span v-if="!isCollapse" slot="title" class="title-text">{{item.meta.title}}</span>
</template>
<!-- 当有子集数据再次使用这个模板,:libraryMenu通过props传递 -->
<Menu :libraryMenu="item.children" @clickLibrary="clickLibrary"></Menu>
</el-submenu>
<el-menu-item
v-else
:index="item.path"
:key="item.path + 'item'"
@click="clickLibrary(item)"
>
<template slot="title">
<i class="iconfont" :class="item.icon"></i>
<span>{{ item.meta.title.length>10?item.meta.title.substr(0, 10) : item.meta.title }}</span>
</template>
</el-menu-item>
</template>
</div>
</template>
<script>
export default {
name: "Menu", //模板名称
props: {
libraryMenu: {
type: Array,
default: [],
},
isCollapse: {
type: Boolean,
default: true
}
},
methods: {
clickLibrary(obj) {
this.$emit("clickLibrary", obj)
},
},
}
</script>
<style lang="less" scoped>
.title-text {
font-size: 16px;
}
.iconfont {
font-size: 18px;
color: aliceblue;
margin-right: 10px;
}
</style>
其实最开始没想到这种方法,是因为我没想到组件还能自己成为自己的子组件,知道了这一点后,动态菜单做起来就非常的简单了,就只需要进行一个判断,判断该组件是不是一个父组件,然后通过组件自己递归来实现动态菜单