Element-UI's NavMenu component implements recursive rendering of deep tree menus

1. When the menu level is relatively deep, it is cumbersome to write the menu level by level. If the menu data is dynamically obtained from the backend, how to dynamically render the menu at the frontend is a problem that needs to be solved. Therefore, consider recursively rendering tree menus. Mainly judge whether the submenu exists, if it exists, recurse. Also use svg to render the menu icon.

Use of svg in Vue project

Recursively render the deep tree menu component menu-content.vue

<!--
  /** 
    *递归渲染深层次树状菜单,并使用svg渲染菜单图标
  */
--> 
<template>
  <div>
    <template v-if="checkDataType(menus) === 'Array'">
      <div v-for="menu in menus" :key="menu.name">
        <el-submenu v-if="menu.children && menu.children.length > 0" :index="menu.name">
          <template slot="title">
            <svg-icon class="svgClass" :icon-class="menu.icon"></svg-icon>
            <span>{
   
   { menu.title }}</span>
          </template>
          <menu-content :menus="menu.children"></menu-content>
        </el-submenu>
        <el-menu-item v-else :index="menu.name">
          <svg-icon class="svgClass" :icon-class="menu.icon"></svg-icon>
          <span>{
   
   { menu.title }}</span>
        </el-menu-item>
      </div>
    </template>
    <el-menu-item v-else :index="menus.name">
      <svg-icon class="svgClass" :icon-class="menu.icon"></svg-icon>
      <span>{
   
   { menu.title }}</span>
    </el-menu-item>
  </div>
</template>
<script>
export default {
  name: 'menu-content',
  props: ['menus'],
  data() {
    return {}
  },
  methods: {
    checkDataType(data) {
      return Object.prototype.toString.call(data).slice(8, -1);
    }
  }
}
</script>
<style scoped>
.svgClass {
  font-size: 18px;
  padding-right: 6px;
  opacity: 0.6;
}
</style>

2. Use recursive components to render the menu aside-menu.vue

<template>
  <el-menu :default-active="activeMenu" @select="menuSelect">
    <menu-content :menus="menus"></menu-content>
  </el-menu>
</template>
<script>
import MenuContent from './menu-content.vue';
export default {
  name: 'aside-menu',
  components: { MenuContent },
  data() {
    return {
      activeMenu: 'Home',
      menus: [{
        id: 1,
        name: 'Home',
        title: '首页',
        path: '/home',
        order: 1,
        icon: 'home',
        parentId: 0,
        visible: true
      },
      {
        id: 2,
        name: 'System',
        title: '系统管理',
        path: '/system',
        order: 2,
        icon: 'system',
        parentId: 0,
        visible: true,
        children: [{
          id: 21,
          name: 'User',
          title: '用户管理',
          path: '/system/user',
          order: 1,
          icon: 'user',
          parentId: 2,
          visible: true
        },
        {
          id: 22,
          name: 'Role',
          title: '角色管理',
          path: '/system/role',
          order: 2,
          icon: 'role',
          parentId: 2,
          visible: true
        },
        {
          id: 23,
          name: 'Menu',
          title: '菜单管理',
          path: '/system/menu',
          order: 3,
          icon: 'menu',
          parentId: 2,
          visible: true
        }]
      },
      {
        id: 3,
        name: 'Monitor',
        title: '系统监控',
        path: '/monitor',
        order: 3,
        icon: 'monitor',
        parentId: 0,
        visible: true,
        children: [{
          id: 31,
          name: 'Online',
          title: '在线用户',
          path: '/monitor/online',
          order: 1,
          icon: 'online',
          parentId: 3,
          visible: true
        },
        {
          id: 31,
          name: 'Statistics',
          title: '统计图表',
          path: '/monitor/statistics',
          order: 2,
          icon: 'statistics',
          parentId: 3,
          visible: true
        }]
      }],
    }
  },
  created() {
    this.activeMenu = this.$route.name;
  },
  methods: {
    menuSelect(index) {
      this.$router.push({ name: index });
    }
  },
}
</script>

Rendering result:

 

Guess you like

Origin blog.csdn.net/sleepwalker_1992/article/details/125645422