vue 动态生成路由菜单(从后端请求到菜单数据,生成左侧菜单栏)

最近在学习vue,用vue+element ui搞一个管理后台的demo,发现网上好多菜单信息都放在前端js文件中,然后后端返回的角色去匹配对应的菜单信息。我自己不太喜欢这种方式,最后自己写了一套登录成功以后,根据用户的角色返回对应的菜单数据,直接在前端进行渲染。

后台体验地址: http://106.13.168.18/#/login    admin 111111

下面只是实现了两级菜单目录,如果要实现多级,可以用递归构建,(ps: 这个后续有时间)

主要还是将后端传来的菜单数据分为两步

1.将数据 "component": Layout组件对象

2.将数据构建为菜单树

import Layout from '../views/layout/Layout'


// data 就是后台传过来的菜单数据,这个数据直接是一个集合就好了,不需要构建菜单树
export function parse_menu(data) {
  let result = getPage(data);
  result.push({path: '*', redirect: '/404', hidden: true})
  return result;
}

/**
 * 构建菜单
 * 
 *
 * @param allList
 * @returns {[]}
 */
function getPage(allList) {
  let tempArr = allList;

  // 构建的菜单数据
  let menuList = [];
  // 获取所有的父级菜单
  allList.forEach((menu, index) => {
    // 一级菜单parentId == 0
    if (menu.parentId === 0) {
      // 判断该菜单是目录还是菜单 0=目录,1=菜单
      let temp;
      if (menu.type === 1) {
        temp = {
          menuId: menu.pageId,
          parentId: menu.parentId,
          path: '',
          component: Layout,
          redirect: '/' + menu.url,
          children: [
            {
              item: 'one',
              path:  menu.url,
              name: menu.name,
              component: resolve => require([`@/views/${menu.url}/index.vue`], resolve),
              meta: {title: menu.name, icon: menu.icon ? menu.icon : 'form'}
            }
          ]
        };
      } else {
        temp = {
          menuId: menu.pageId,
          parentId: menu.parentId,
          path: '/' + menu.url,
          name: menu.name,
          component: Layout,
          redirect: '/dashboard',
          meta: {title: menu.name, icon: menu.icon ? menu.icon : 'form'},
          children: []
        };
      }
      menuList.push(temp);
    }
  });

  menuList.forEach((menu, index) => {
    menu.children = menu.children.concat(getChild(menu.menuId, allList))
  })

  return menuList;
}

/**
 *  构建子菜单数据
 *
 * @param menuId
 * @param menuArr
 * @returns {[]}
 */
function getChild(menuId, allList) {
  let chileArr = [];
  allList.forEach((menu, index) => {

    // 遍历所有节点,将父菜单id与传过来的id比较
    if (menu.parentId !== 0) {
      if (menu.parentId === menuId) {
        let temp;
        if (menu.type === 1) {
          temp = {
            menuId: menu.pageId,
            parentId: menu.parentId,
            path: menu.url,
            name: menu.name,
            component: resolve => require([`@/views/${menu.url}/index.vue`], resolve),
            meta: {title: menu.name, icon: menu.icon ? menu.icon : 'form'}
          }
        }
        chileArr.push(temp);
      }
    }
  })
  return chileArr;
}

后端的菜单表

 

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值