美文网首页
vue菜单组件

vue菜单组件

作者: 小米和豆豆 | 来源:发表于2021-09-28 09:28 被阅读0次

新建navMenu文件夹 => index.vue + navMenu.vue

  1. 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>
  1. 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>

相关文章

网友评论

      本文标题:vue菜单组件

      本文链接:https://www.haomeiwen.com/subject/mnoagltx.html