側邊欄導航菜單在日常 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> 複製代碼