elementUI 多级菜单动态渲染

侧边栏导航菜单在日常 CMS 管理平台开发中很常见,最近在产品开发中就遇到难题:html

公司采用的是 vue + element 技术栈,element 文档中 NavMenu 是写死的,而不是经过数据渲染的,菜单多、层级深的时候,就很鸡肋...vue

再参考 此连接 后,再结合本身需求,组装成 kgMenu 组件git

kgMenu 里面封装 kgSubMenu、kgMenuGroup、kgMenuItem 三个基础组件bash

kgMenuItem.vuemarkdown

// kgMenuItem
<template>
  <el-menu-item :index="menu.index" :route="menu.route.path">
    <template>
      <i :class="menu.icon"></i><span slot="title">{{ menu.lable }}</span>
    </template>
  </el-menu-item>
</template>

<script>
export default {
  name: 'kgMenuItem',
  props: {
    menu: {
      type: Object
    }
  },
  data () {
    return {}
  }
}
</script>
复制代码

kgSubMenu.vueoop

// kgSubMenu.vue
<template>
  <el-submenu v-if="menu.type === 'submenu'" :index="menu.index">
    <template slot="title" v-if="menu.lable !== null">
      <i :class="menu.icon"></i>
      <span slot="title">{{ menu.lable }}</span>
    </template>
    <template v-if="menu.childs !== null">
      <template v-for="menuItem in menu.childs">
        <template v-if="menuItem.type === 'item'">
          <kg-menu-item :menu="menuItem" :key="menuItem.id"></kg-menu-item>
        </template>
        <template v-if="menuItem.type === 'submenu'">
          <kg-sub-menu :menu="menuItem" :key="menuItem.id"></kg-sub-menu>
        </template>
        <template v-if="menuItem.type === 'group'">
          <kg-menu-group :menu="menuItem" :key="menuItem.id"></kg-menu-group>
        </template>
      </template>
    </template>
  </el-submenu>
</template>

<script>
import kgMenuItem from './kgMenuItem'
import kgMenuGroup from './kgMenuGroup'

export default {
  name: 'kgSubMenu',
  props: {
    menu: {
      type: Object
    }
  },
  components: {kgMenuItem, kgMenuGroup},
  data () {
    return {}
  }
}
</script>
复制代码

kgMenuGroup.vuepost

// kgMenuGroup.vue
<template>
  <el-menu-item-group>
    <template slot="title" v-if="menu.lable !== null">
      <i :class="menu.icon"></i>
      <span slot="title">{{ menu.lable }}</span>
    </template>
    <template v-if="menu.childs !== null">
      <template v-for="menuItem in menu.childs">
        <template v-if="menuItem.type === 'item'">
          <kg-menu-item :menu="menuItem" :key="menuItem.id"></kg-menu-item>
        </template>
        <template v-if="menuItem.type === 'submenu'">
          <kg-sub-menu :menu="menuItem" :key="menuItem.id"></kg-sub-menu>
        </template>
      </template>
    </template>
  </el-menu-item-group>
</template>

<script>
import kgMenuItem from './kgMenuItem'
import kgSubMenu from './kgSubMenu'

export default {
  name: 'kgMenuGroup',
  props: {
    menu: {
      type: Object
    }
  },
  components: {kgMenuItem, kgSubMenu},
  data () {
    return {}
  }
}
</script>
复制代码

kgMenu.vueui

<template>
  <el-menu
    :background-color="settings.backgroundColor"
    :text-color="settings.textColor"
    :router="settings.router"
    :active-text-color="settings.activeTextColor">
    <template v-for="menuItem in leftMenus">
      <template v-if="menuItem.type === 'item'">
        <kg-menu-item :menu="menuItem" :key="menuItem.id"></kg-menu-item>
      </template>
      <template v-if="menuItem.type === 'submenu'">
        <kg-sub-menu :menu="menuItem" :key="menuItem.id"></kg-sub-menu>
      </template>
      <template v-if="menuItem.type === 'group'">
        <kg-menu-group :menu="menuItem" :key="menuItem.id"></kg-menu-group>
      </template>
    </template>
  </el-menu>
</template>

<script>
import kgMenuItem from './kgMenuItem'
import kgSubMenu from './kgSubMenu'
import kgMenuGroup from './kgMenuGroup'

export default {
  name: 'kgMenu',
  props: {
    leftMenus: {
      type: Array
    },
    settings: {
      type: Object
    }
  },
  components: {kgMenuItem, kgSubMenu},
  data () {
    return {}
  }
}
</script>

复制代码

封装好后,在须要调用的调用 kgMenu 便可, 经过 props 传递菜单数据 leftMenus 和 菜单设置 settings,spa

\\ index.vue
<template>
    <div>
        ...
        <kg-menu :leftMenus="menuList" :settings="menuSetting"></kg-menu>
        ...
    </div>
</template>

<script>
import kgMenu from '../kgMenu'
export default {
    components: {kgMenu},
    date () {
        return {
            menuSetting: {
                backgroundColor: '#333743',
                textColor: '#909399',
                activeTextColor: '#909399',
                defaultOpeneds: [],
                uniqueOpened: true,
                router: true,
                collapseTransition: true
            },
            menuList: [
                {
                  id: 0,
                  type: 'item',
                  index: 'home',
                  lable: '首页',
                  icon: 'el-icon-circle-plus-outline',
                  route: {
                    type: 'inner',
                    path: {name: 'KgGainIframe', params: {'postfix': 'D2R'}}
                  }
                },
                {
                  id: 1,
                  type: 'submenu',
                  index: 'news',
                  lable: '新闻',
                  icon: 'ic-association-analysis',
                  childs: [
                    {
                      id: 0,
                      type: 'item',
                      index: 'addNews',
                      lable: '发布新闻',
                      route: {
                        type: 'inner',
                        path: {name: 'KgAddNews'}
                      }
                    },
                    {
                      id: 1,
                      type: 'item',
                      index: 'newsList',
                      lable: '新闻列表',
                      route: {
                        type: 'inner',
                        path: {name: 'KgNewsList'}
                      }
                    }
                  ]
                }
                ...
           ] 
        }
    }
}
</script>
复制代码
相关文章
相关标签/搜索