美文网首页前端开发那些事儿vue
vue实现页面权限中的菜单配置

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

作者: 闲余幽梦 | 来源:发表于2020-04-14 23:45 被阅读0次

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

    框架和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

    效果

    相关文章

      网友评论

        本文标题:vue实现页面权限中的菜单配置

        本文链接:https://www.haomeiwen.com/subject/edcezctx.html