当前位置:   article > 正文

vue-element-admin从后台动态查询菜单并生成路由信息_vue-element-admin 菜单通过接口展示

vue-element-admin 菜单通过接口展示

项目是gitee下载的 地址 https://gitee.com/panjiachen/vue-element-admin

由于分支较多,最初我下载的master版本的 ,但是权限版本比较老了,权限这块我使用的是

vue-element-admin权限验证: vue-element-admin权限验证,根据不同角色动态生成路由渲染侧边栏https://gitee.com/gsx1992/vue-element-admin.git这个里面的, 修改最大的地方就是 src/store/modules/permission.js文件,从后台获取的动态路由格式为:

  1. export const asyncRoutes = [
  2. {
  3. path: '/app',
  4. component: Layout,
  5. redirect: 'noRedirect',
  6. name: 'appmanager',
  7. title: '店铺管理',
  8. icon: 'el-icon-s-help',
  9. alwaysShow: true, // 始终显示根目录
  10. children: [
  11. {
  12. path: 'applist',
  13. component: 'lass/app/index',
  14. name: 'appmanagerlist',
  15. title: '渠道列表',
  16. icon: 'el-icon-s-help'
  17. }
  18. ]
  19. },
  20. {
  21. path: '/user',
  22. component: Layout,
  23. redirect: 'noRedirect',
  24. name: 'System',
  25. title: '系统管理',
  26. icon: 'el-icon-s-help',
  27. children: [
  28. {
  29. path: 'userlist',
  30. component: 'lass/user/index',
  31. name: 'user',
  32. title: '用户管理',
  33. icon: 'el-icon-s-help'
  34. },
  35. {
  36. path: 'rolelist',
  37. component: 'lass/user/role/index',
  38. name: 'RoleList',
  39. title: '角色管理',
  40. icon: 'el-icon-s-help'
  41. },
  42. {
  43. path: 'lass/user/role/detail/:id(\\d+)',
  44. component: 'lass/user/role/detail',
  45. name: 'Roledetail',
  46. title: '角色列表',
  47. activeMenu: '/lass/user/role/orglist',
  48. icon: 'el-icon-s-help'
  49. }
  50. ]
  51. },
  52. {
  53. path: '/task',
  54. component: Layout,
  55. redirect: 'noRedirect',
  56. name: 'Task',
  57. title: '定时任务管理',
  58. icon: 'el-icon-s-help',
  59. alwaysShow: true, // 始终显示根目录
  60. children: [
  61. {
  62. path: 'list',
  63. component: 'lass/task/list',
  64. name: 'TaskList',
  65. title: '任务列表',
  66. icon: 'el-icon-s-help'
  67. }
  68. ]
  69. },
  70. {
  71. path: '/costList',
  72. component: Layout,
  73. redirect: '/costList/index',
  74. title: 'SKU系统管理',
  75. name: 'cost',
  76. icon: 'link',
  77. children: [
  78. {
  79. path: 'skuindex',
  80. component: 'lass/skusysList/skuindex',
  81. name: 'skuindex',
  82. title: 'sku计费列表',
  83. icon: 'guide',
  84. type: 4,
  85. url: 'admin/skusysList/skuindex'
  86. },
  87. {
  88. path: 'supplier',
  89. component: 'lass/skusysList/supplier',
  90. name: 'supplierList',
  91. title: '供应商管理',
  92. icon: 'guide',
  93. type: 4,
  94. url: 'admin/supplier/index'
  95. }
  96. ]
  97. },
  98. ]

 其中store里面的permission.js目录如下:

 代码修改如下:

  1. import { constantRoutes } from '@/router'
  2. import { formatRouter, getIframeIdList, save } from '@/utils'
  3. // 自定义多维数组包特定对象转一维数组过滤children,后端若返回一维数组则直接交由filterAsyncRoutes处理
  4. function MultidimensionalToOnedimensional(routesMap) {
  5. const filterRoutesMap = []
  6. !(function fn(routesMap) {
  7. routesMap.forEach(route => {
  8. const tmp = {}
  9. for (const key in route) {
  10. if (Object.hasOwnProperty.call(route, key)) {
  11. if (key !== 'children') {
  12. tmp[key] = route[key]
  13. } else if (key === 'children') {
  14. fn(route[key])
  15. }
  16. }
  17. }
  18. filterRoutesMap.push(tmp)
  19. })
  20. }(routesMap))
  21. return filterRoutesMap
  22. }
  23. // 路由索引匹配
  24. export function filterAsyncRoutes(routes, filterRoutesMap) {
  25. const accessedRoutes = []
  26. routes.forEach(route => {
  27. const tmp = {}
  28. if (filterRoutesMap.some(a => a.path === route.path)) {
  29. for (const key in route) {
  30. if (Object.hasOwnProperty.call(route, key)) {
  31. if (key !== 'children') {
  32. tmp[key] = route[key]
  33. } else if (key === 'children') {
  34. const tmpC = filterAsyncRoutes(route[key], filterRoutesMap);
  35. (tmpC.length > 0) && (tmp.children = tmpC)
  36. }
  37. }
  38. }
  39. }
  40. tmp.path && accessedRoutes.push(tmp)
  41. })
  42. return accessedRoutes
  43. }
  44. const getDefaultState = () => {
  45. return {
  46. routes: [],
  47. addRoutes: [],
  48. iframePages: {}
  49. }
  50. }
  51. const state = getDefaultState
  52. const mutations = {
  53. SET_ROUTES: (state, routes) => {
  54. routes.push({ path: '*', redirect: '/404', hidden: true })
  55. state.addRoutes = routes
  56. state.routes = constantRoutes.concat(routes)
  57. // state.routes.push({ path: '*', redirect: '/404', hidden: true })
  58. },
  59. RESET_STATE: state => {
  60. Object.assign(state, getDefaultState())
  61. },
  62. setIframeIds(state, iframePages) {
  63. if (typeof iframePages !== 'string' && iframePages) {
  64. state.iframePages = JSON.stringify(iframePages)
  65. } else {
  66. state.iframePages = iframePages
  67. }
  68. save('iframePages', state.iframePages)
  69. }
  70. }
  71. const actions = {
  72. generateRoutes({ commit, dispatch }, { asyncRoutes, routesMap }) {
  73. const loadMenuData = []
  74. let formatRutes = []
  75. Object.assign(loadMenuData, JSON.parse(asyncRoutes))
  76. const tempAsyncRoutes = Object.assign([], [])
  77. // 格式化路由
  78. formatRutes = formatRouter(tempAsyncRoutes, loadMenuData)
  79. // 获取iframe外链列表
  80. const iframeList = getIframeIdList([], JSON.parse(asyncRoutes), {})
  81. const asyncFormatRoutes = formatRutes
  82. const routesFormatMap = asyncFormatRoutes
  83. return new Promise(resolve => {
  84. const filterRoutesMap = MultidimensionalToOnedimensional(routesFormatMap)
  85. const accessedRoutes = filterAsyncRoutes(asyncFormatRoutes, filterRoutesMap)
  86. commit('SET_ROUTES', accessedRoutes)
  87. if (iframeList) {
  88. commit('setIframeIds', iframeList)
  89. // 设置iframe外链列表
  90. dispatch('iframes/setPage', iframeList, { root: true })
  91. }
  92. resolve(accessedRoutes)
  93. })
  94. },
  95. resetState({ commit }) {
  96. return new Promise(resolve => {
  97. commit('RESET_STATE')
  98. resolve()
  99. })
  100. }
  101. }
  102. export default {
  103. namespaced: true,
  104. state,
  105. mutations,
  106. actions
  107. }

 其中路由从接口返回后,转换动态路由的方法formatRouter的代码如下:

  1. /**
  2. * 后台查询的菜单数据拼装成路由格式的数据
  3. * @param routes
  4. * @param data
  5. */
  6. export function formatRouter(routes, data) {
  7. const len = data.length
  8. for (let i = 0; i < len; i++) {
  9. const menu = {
  10. path: data[i].path,
  11. component: Layout,
  12. alwaysShow: data[i].alwaysShow,
  13. redirect: data[i].redirect,
  14. name: data[i].name,
  15. meta: { title: data[i].title, noCache: true, icon: data[i].icon },
  16. children: []
  17. }
  18. if (data[i].children) {
  19. const children = data[i].children
  20. for (let j = 0; j < children.length; j++) {
  21. let metaSet = {}
  22. if (children[j].activeMenu && children[j].activeMenu !== undefined) {
  23. metaSet = { title: children[j].title, noCache: true, activeMenu: children[j].activeMenu }
  24. } else {
  25. metaSet = { title: children[j].title, noCache: true }
  26. }
  27. const viewPath = children[j].component
  28. var childrenList = {
  29. path: children[j].path,
  30. component: (resolve) => require([`@/views/${viewPath}`], resolve),
  31. name: children[j].name,
  32. meta: metaSet,
  33. hidden: children[j].hasOwnProperty('hidden') ? children[j].hidden : false
  34. }
  35. menu.children.push(childrenList)
  36. }
  37. }
  38. routes.push(menu)
  39. }
  40. return routes
  41. }

以上就是从后台动态查询菜单并生成路由信息的改动,原来的demo版本权限是在前端控制,也就是把每页路由的角色带上,实际一般都是从后台动态 获取来控制,这个和demo有点区别。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/58954
推荐阅读
相关标签
  

闽ICP备14008679号