element UI如何实现多级导航菜单动态生成

215 阅读1分钟

最近在开发中遇见了一些问题,就是如何让多级菜单根据路由来实现动态显示。 最开始的想法是使用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>

其实最开始没想到这种方法,是因为我没想到组件还能自己成为自己的子组件,知道了这一点后,动态菜单做起来就非常的简单了,就只需要进行一个判断,判断该组件是不是一个父组件,然后通过组件自己递归来实现动态菜单