側邊欄導航選單在平常 CMS 管理平臺開發中很常見,最近在產品開發中就遇到難題:
公司採用的是 vue + element 技術棧,element 文件中 NavMenu 是寫死的,而不是通過資料渲染的,選單多、層級深的時候,就很雞肋...
再參考 此連結 後,再結合自己需求,組裝成 kgMenu 元件
kgMenu 裡面封裝 kgSubMenu、kgMenuGroup、kgMenuItem 三個基礎元件
kgMenuItem.vue
// 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.vue
// 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.vue
// 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.vue
<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,
\\ 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>
複製程式碼