通過一個數(shù)組渲染菜單棒动,實現(xiàn)頁面權限的自動配置吼虎。
框架和UI選擇
- vue
- vue-router
- element-ui
- vuex
思路
n級菜單有n-1級菜單構成......以此類推可得:多級菜單就是通過二級菜單循環(huán)構成。在element-ui中找到NavMenu 導航菜單
組件寻歧,使用該組件做一個二級菜單的循環(huán)體組件胸囱。菜單數(shù)據(jù)存儲在vuex中祷舀。
基礎菜單的循環(huán)體組件(以二級菜單為例)
在組件中判斷是否有子集來加載不同的模塊。二級菜單內部通過插槽來加載循環(huán)生成的一級組件數(shù)組,如下list-item
組件
// index屬性可以用菜單對象中的屬性代替(item.key之類的)
// 菜單下拉區(qū)域裳扯,在有子集的情況下渲染
<el-submenu v-if="item.sonList" :index="i">
<template slot="title">
<i v-if="item.icon" :class="item.icon" />
<span>{{ item.name }}</span>
</template>
// 放置前一級菜單的循環(huán)節(jié)點
<slot />
</el-submenu>
// 單行菜單區(qū)域抛丽,無子集的情況下渲染
<el-menu-item v-else :index="i">
<i v-if="item.icon" :class="item.icon" />
<router-link slot="title" :to="item.path">
{{ item.name }}
</router-link>
</el-menu-item>
index屬性可以用菜單對象中的任意屬性代替只需要它是唯一的
通過遞歸函數(shù)獲取樹型結構的菜單列表
- 渲染菜單列表
render (createElement) {
let domArr = []
let path = '/routeD' // 根路由,可以自定義
// arr:子集節(jié)點饰豺,zIndex:層級(用于生成index)
const reduceFun = function (arr, zIndex) {
const lArr = []
for (let i = 0; i < arr.length; i++) {
const el = JSON.parse(JSON.stringify(arr[i]))
let index
let domList = null
// 用于生成唯一的index亿鲜,如果使用菜單中的屬性的話可以去除zIndex和該段邏輯
if (zIndex !== 1) {
index = zIndex + '-' + i
} else {
index = i.toString()
}
if (!el.path.includes('/')) {
el.path = path + '/' + el.path
}
if (el.sonList) {
path = el.path
const domObj = reduceFun(el.sonList, index)
let arrPath = el.path.split('/')
path = arrPath.slice(0,-1).join('/')
domList = domObj.lArr
}
const dom = createElement('list-item', {
props: {
item: el,
i: el.key || i.toString()
}
}, domList)
lArr.push(dom)
}
return {
lArr
}
}
const obj = reduceFun(this.$store.getters.meanList, 1)
domArr = obj.lArr
return createElement('el-menu', {
class: 'el-menu-vertical-demo',
props: {
'default-active': '1'
},
on: {
select (obj) {
console.log(obj)
}
}
}, domArr)
}
- 根據(jù)菜單數(shù)據(jù)動態(tài)添加路由
// 導入路由中的權限路由
import { powerRoute } from '@/router'
····
// 遞歸獲取菜單數(shù)據(jù)中的路由,再通過addRoutes添加路由
const reduceFun = function (arr) {
const routes = []
for (let i = 0; i < arr.length; i++) {
const el = arr[i]
let routeObj = {}
routeObj = {
path: el.path,
component: el.component
}
if (el.sonList) {
const childRoute = reduceFun(el.sonList)
routeObj.children = childRoute
}
routes.push(routeObj)
}
return routes
}
const routes = reduceFun(this.$store.getters.meanList)
let oldR = powerRoute[0]
oldR.children = routes
this.$router.addRoutes([oldR])
····
從后臺獲取不同角色的不同菜單數(shù)據(jù)哟忍,再通過兩個遞歸函數(shù)來渲染菜單和動態(tài)添加菜單路由狡门,實現(xiàn)頁面的權限配置。
演示
https://erpang123.github.io/router-demo/dist-demo/index.html
完整案例:https://github.com/erpang123/router-demo