elementUI 多級選單動態渲染

Alone1469546971808發表於2018-08-28

側邊欄導航選單在平常 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>
複製程式碼

相關文章