vue-element-admin实现后台接口返回路由,前端动态生成路由菜单

最近要开发新项目,与以往不同的是,路由菜单的生成都是需要后台管理的,接口直接返回给前端,前端根据接口的返回实现菜单及页面的显示。
在菜单还没有给数据的时候,前端先自己在mock中模拟实现一下功能。
实现后的效果如下图所示:
效果图接下来就是实现过程:

1、修改router/index.js

首先找到router/index.js,需要对asyncRoutes进行修改,将asyncRoutes中原本的菜单全部复制并删掉,这部分内容要换到接口返回的数据中。
页面效果图正常如果我们直接在前端页面写路由的话是如下写法:

/**
* asyncRoutes
* 需要根据用户角色动态加载的路由
*/
export const asyncRoutes = [
  {
    path: '/advancedConfig',
    component: Layout,
    name: 'AdvancedConfig',
    meta: {
      title: '一级菜单--11',
      icon: 'user'
    },
    children: [
      {
        path: 'roleType',
        component: () => import('@/views/advancedConfig/roleType'),
        name: 'RoleType',
        meta: { title: '二级菜单--12' }
      },
      {
        path: 'userRights',
        component: () => import('@/views/advancedConfig/userRights'),
        name: 'UserRights',
        meta: { title: '二级菜单--13' }
      }
    ]
  },
  {
    path: '/advancedConfig1',
    component: Layout,
    name: 'AdvancedConfig1',
    meta: {
      title: '一级菜单--11',
      icon: 'user'
    },
    children: [
      {
        path: 'employeeAuthority',
        component: () => import('@/views/advancedConfig/employeeAuthority'),
        name: 'EmployeeAuthority',
        meta: { title: '二级菜单--221' }
      },
      {
        path: 'userFunction',
        component: () => import('@/views/advancedConfig/userFunction'),
        name: 'UserFunction',
        meta: { title: '二级菜单--221' }
      }
    ]
  },
  /** when your routing map is too long, you can split it into small modules **/
  // 404 page must be placed at the end !!!
  { path: '*', redirect: '/404', hidden: true }
]

将上面asyncRoutes中的代码全部复制到mock/user.js中,剩余asyncRoutes如下:

export const asyncRoutes = []

2、修改mock/user.js

找到 url: ‘/vue-element-admin/user/info.*’,将刚刚第一步那边删除的路由放到这边来,放置位置如下图所示:
放置位置注意:直接粘贴过来肯定会报错,所以这边粘贴完成后要对路由中的layout和component进行修改,具体修改如下:

component: Layout  改为:  component:'Layout'
component: () => import('@/views/advancedConfig/roleType'),   改为:component: ('advancedConfig/roleType'),

修改后的效果图下图所示,可以对比router/index.js中删除的内容看看,就是做了一些微调。
对比效果图mock/user.js代码:

// get user info
{
  url: '/vue-element-admin/user/info\.*',
  type: 'get',
  response: config => {
    const { token } = config.query
    const info = users[token]
    info.menuTree = [
      {
        path: '/advancedConfig',
        component: 'Layout',
        name: 'AdvancedConfig',
        meta: {
          title: '一级菜单--11',
          icon: 'user'
        },
        children: [
          {
            path: 'roleType',
            component: ('advancedConfig/roleType'),
            name: 'RoleType',
            meta: {
              title: '二级菜单--12'
            }
          },
          {
            path: 'userRights',
            component: ('advancedConfig/userRights'),
            name: 'UserRights',
            meta: {
              title: '二级菜单--13'
            }
          }
        ]
      },
      {
        path: '/advancedConfig1',
        component: 'Layout',
        name: 'AdvancedConfig1',
        meta: {
          title: '一级菜单--22',
          icon: 'user'
        },
        children: [
          {
            path: 'employeeAuthority',
            component: ('advancedConfig/employeeAuthority'),
            name: 'EmployeeAuthority',
            meta: { title: '二级菜单--21' }
          },
          {
            path: 'userFunction',
            component: ('advancedConfig/userFunction'),
            name: 'UserFunction',
            meta: { title: '二级菜单--22' }
          }
        ]
      },
      {
        path: '*',
        redirect: '/404',
        hidden: true
      }
    ]
    // mock error
    if (!info) {
      return {
        code: 50008,
        message: 'Login failed, unable to get user details.'
      }
    }


    return {
      code: 20000,
      data: info
    }
  }
},

这边需要注意的是,路由最下面一堆要加上404配置,上面的代码中就是加在路由最下方
404页面如果不配置404,会报错。

3、修改src/permission.js

需要修改的地方如下图所示,只要将我下方的代码粘贴进去替换原有即可。
修改地方代码如下:

try {
  // 获取用户信息
  // 注意:角色必须是一个对象数组!例如:['admin']或['developer','editor']
  const data = await store.dispatch('user/getInfo')
  // console.log(data)
  // 根据角色生成可访问路由映射
  const accessRoutes = await store.dispatch('permission/generateRoutes', data)
  // 动态添加可访问路由
  router.addRoutes(accessRoutes)
  // hack方法来确保adroutes是完整的
  // 设置replace: true,这样导航就不会留下历史记录
  next({ ...to, replace: true })
}

4、修改src/store/modules/permission.js

4-1、修改 generateRoutes方法

如下图所示,对代码进行修改:
修改代码如下:

const actions = {
  generateRoutes({ commit }, data) {
    return new Promise(resolve => {
      const accessedRoutes = filterAsyncRoutes(data.menuTree, data.roles)
      commit('SET_ROUTES', accessedRoutes)
      resolve(accessedRoutes)
    })
  }
}

4-2、修改 filterAsyncRoutes方法

在修改 filterAsyncRoutes方法的时候还加了对layout和component的处理,具体修改如下图所示:
修改代码如下:



/**
* Filter asynchronous routing tables by recursion
* @param routes asyncRoutes
* @param roles
*/
export function filterAsyncRoutes(routes, roles) {
  const list = []
  routes.forEach(p => {
    if (hasPermission(roles, p)) {
      p.component = () => import('@/layout')
      if (p.children != null) {
        p.children = getChildren(p.children)
      }
      list.push(p)
    }
  })
  return list
}
export const loadView = (view) => {
  return (resolve) => require([`@/views/${view}`], resolve)
}
function getChildren(data) {
  const array = []
  data.forEach(x => {
    const children = JSON.parse(JSON.stringify(x))
    children.component = loadView(x.component)
    if (x.children != null) {
      children.children = getChildren(x.children)
    }
    array.push(children)
  })
  return array
}

到此就可以实现动态路由的效果了,参考地址

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值