vue实现页面权限中的菜单配置

通过一个数组渲染菜单,实现页面权限的自动配置。

框架和UI选择

  1. vue
  2. vue-router
  3. element-ui
  4. vuex

思路

n级菜单有n-1级菜单构成......以此类推可得:多级菜单就是通过二级菜单循环构成。在element-ui中找到NavMenu 导航菜单组件,使用该组件做一个二级菜单的循环体组件。菜单数据存储在vuex中。

基础菜单的循环体组件(以二级菜单为例)

在组件中判断是否有子集来加载不同的模块。二级菜单内部通过插槽来加载循环生成的一级组件数组,如下list-item组件

// index属性可以用菜单对象中的属性代替(item.key之类的)
// 菜单下拉区域,在有子集的情况下渲染
  <el-submenu v-if="item.sonList" :index="i">
    <template slot="title">
      <i v-if="item.icon" :class="item.icon" />
      <span>{{ item.name }}</span>
    </template>
    // 放置前一级菜单的循环节点
    <slot />
  </el-submenu>
// 单行菜单区域,无子集的情况下渲染
  <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属性可以用菜单对象中的任意属性代替只需要它是唯一的

通过递归函数获取树型结构的菜单列表
  1. 渲染菜单列表
render (createElement) {
    let domArr = []
    let path = '/routeD'  // 根路由,可以自定义
    // arr:子集节点,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)
  }
  1. 根据菜单数据动态添加路由
// 导入路由中的权限路由
import { powerRoute } from '@/router'
····
// 递归获取菜单数据中的路由,再通过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])
····

从后台获取不同角色的不同菜单数据,再通过两个递归函数来渲染菜单和动态添加菜单路由,实现页面的权限配置。

演示

https://erpang123.github.io/router-demo/dist-demo/index.html

完整案例:https://github.com/erpang123/router-demo

效果

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容

  • 基于Vue的一些资料 内容 UI组件 开发框架 实用库 服务端 辅助工具 应用实例 Demo示例 element★...
    尝了又尝阅读 1,140评论 0 1
  • UI组件 element- 饿了么出品的Vue2的web UI工具套件 Vux- 基于Vue和WeUI的组件库 m...
    小姜先森o0O阅读 9,395评论 0 72
  • UI组件 element- 饿了么出品的Vue2的web UI工具套件 Vux- 基于Vue和WeUI的组件库 m...
    王喂马_阅读 6,441评论 1 77
  • UI组件 element- 饿了么出品的Vue2的web UI工具套件 Vux- 基于Vue和WeUI的组件库 m...
    你猜_3214阅读 11,035评论 0 118
  • UI组件 element- 饿了么出品的Vue2的web UI工具套件 Vux- 基于Vue和WeUI的组件库 m...
    流觞小菜鸟阅读 1,745评论 2 8