新建navMenu文件夹 => index.vue + navMenu.vue
- index.vue
<!--
* @Author: your name
* @Date: 2021-09-08 20:53:56
* @use: <NavMenu :propsData="list"/> list [{name:'',children:[]}]格式的树形结构
-->
<template>
<div class='navMenu pr'>
<span class="open_icon pa" @click="collapse=!collapse">
<i v-bind:class="!collapse?'el-icon-s-fold':'el-icon-s-unfold'"></i>
</span>
<el-menu
:default-active="active"
class="el-menu-vertical-demo"
background-color="#000"
text-color="#fff"
:collapse="collapse"
@open="handleOpen"
@close="handleClose">
<menu-item :propsData="propsData"/>
</el-menu>
</div>
</template>
<script>
import menuItem from './menuItem.vue'
import { mapGetters } from "vuex";
export default {
name:'navMenu',
components:{
menuItem
},
props:{
propsData:{
type:Array,
default:()=>[]
}
},
data(){
return{
collapse:false,
active:''
}
},
computed:{
...mapGetters('User',['asyncRoutesObj']), //处理后的asyncRoutes {name[route.name]: {route}}
},
watch: {
$route:{
handler(){
let parent=this.$route.matched[this.$route.matched.length-1].parent;
let route=this.asyncRoutesObj[parent.name].children||[]
if(route.every(item=>item.hidden)) this.active = parent.name;
else this.active =this.$route.name;
},
deep:true,
immediate:true
}
},
methods: {
handleOpen(key, keyPath) {
this.$emit('handleOpen',{key,keyPath})
},
handleClose(key, keyPath) {
this.$emit('handleClose',{key,keyPath})
}
},
mounted () {
// this.active = this.$route.name;
},
};
</script>
<style lang="scss">
.el-menu-item.is-active{
color: #fff !important;
background-color: #F36514 !important;
}
</style>
<style scoped lang='scss'>
.navMenu{
width: max-content;
height: 100%;
.open_icon{
right: 0px;
bottom: 0px;
font-size: .26rem;
line-height: .26rem;
z-index:99;
color: rgb(230, 230, 230);
}
.el-menu{
height: 100%;
overflow:auto;
}
.el-menu-vertical-demo:not(.el-menu--collapse) {
width:220px;
}
}
</style>
- menuItem.vue
<!--
* @Author: DDY
* @Date: 2021-09-08 21:21:24
* @description: 根据具体的业务取对应的字段渲染
-->
<template>
<div class="menuItem">
<template v-for="item of propsData">
<el-submenu :key="item.name" v-if="item.children && item.children.length&&!item.hidden&&hasChild(item.children)" :index="item.name" >
<template slot="title">
<i v-bind:class="item.meta&&item.meta.icon"></i>
<span>{{ item.meta&&item.meta.title }}</span>
</template>
<MenuItem :propsData="item.children"/>
</el-submenu>
<el-menu-item :key="item.name" v-if="(!item.children || !item.children.length||!hasChild(item.children))&&!item.hidden" :index="item.name" @click="linkTo(item)">
<i v-bind:class="item.meta&&item.meta.icon"></i>
<span slot="title">{{ item.meta&&item.meta.title }}</span>
</el-menu-item>
</template>
</div>
</template>
<script>
import MenuItem from './menuItem.vue'
export default {
name: "MenuItem",
components:{
MenuItem
},
props: {
propsData: {
type: Array,
default: () => [],
},
},
data() {
return {};
},
methods:{
linkTo(data){
this.$router.push({
name:data.name
}).catch(err=>{})
},
/**
* @description: 判断是否真正的拥有子集(能在菜单显示出来的)
* @return {*} Boolean
*/
hasChild(data){
if(data.every(item=>item.hidden)) return false
return true
}
},
mounted() {
// console.log('this.propsData',this.propsData)
},
};
</script>
<style scoped lang='scss'>
/*隐藏文字*/
.el-menu--collapse .el-submenu__title span{
display: none;
}
/*隐藏 > */
.el-menu--collapse .el-submenu__title .el-submenu__icon-arrow{
display: none;
}
</style>
网友评论