Vue-element-admin: 跪求版主 增加动态菜单

Created on 16 Nov 2017  ·  27Comments  ·  Source: PanJiaChen/vue-element-admin

首先感谢版主分享,同时还希望有空的时候能加一下动态菜单的功能,万分感激。

动态菜单:
router完全由后台配置,通过请求获得 router信息,前端 再通过 addRouter实现真正可访问的路由,
比如:
"path":"/menuTwo", "component":"Home", "name":"导航2", "iconCls":"el-icon-setting", "leaf":false, "children":[ { "path":"menuTwoone", "component":"Main", "leaf":true, "name":"导航2--1级菜单1" }, { "path":"menuTwotwo", "component":"Main", "leaf":true, "hidden":true, "name":"导航2--1级菜单2" } ] 这个数据是 通过请求获得的Json数据,再把这个数据与前段相关的组件联系在一起,生成路由和菜单,本人新手 尝试 做这个功能,无奈,老是报 路径‘xx’是字符串,请使用真正的组件 这个错误。

Most helpful comment

我是这样写的:

//router/index.js
export const routerMap={
 table:_import('table/index')
}
//通过后台请求的路由表,写法跟原本的一样,需要改的地方是component这里,改成map里面组件对应的key值
[
   {
     path: '/table,
     component: 'table',
     redirect: 'noredirect',
     name: 'table',
    }
]
//store/modules/permission.js
import { constantRouterMap, map } from '@/router/index'
// 将本地routerMap映射到ajax获取到的serverRouterMap;
function generateAsyncRouter(routerMap, serverRouterMap) {
  serverRouterMap.forEach(function (item, index) {
    item.component = routerMap[item.component]
    if(item.children && item.children.length > 0){
      generateAsyncRouter(routerMap, item.children)
    }
  })
  return serverRouterMap;
}
//然后在actions中GenerateRoutes方法合适的地方将后端请求的路由表映射到routerMap,并筛选出可访问的路由,serverRouterMap是我定义的从后台请求路由表的方法
serverRouterMap().then(response => {
          var asyncRouterMap = generateAsyncRouter(routerMap, response.data.serverRouterMap)
          if (roles.indexOf('admin') >= 0) {
            accessedRouters = asyncRouterMap
          } else {
            accessedRouters = filterAsyncRouter(asyncRouterMap, roles)
          }
          commit('SET_ROUTERS', accessedRouters)
          resolve()
        })

All 27 comments

路由表里面的这个component是字符串路径,请求获取后,在本地map到相对应的组件就可以了

感谢回答,大哥能贴一下你代码吗?我实在是搞不定啊!先看看我的
Map:
`const _import = require('./_import_' + process.env.NODE_ENV)
import Layout from '../views/layout/Layout'

export const RouterMap={
Layout:Layout,
basicparamIndex:_import('svg-icons/index')
} Map 与后端数据替换: export function generaMenu(data){
console.log("参数:"+data)
var routers=[]
data.forEach((item)=>{
let menu = Object.assign({},item)

console.log("menu:"+menu.component)
console.log("RouterMap:"+RouterMap['Layout'])
menu.component = RouterMap[menu.component]
// if(!item.leaf){
//   menu.children = []
//   generaMenu(item.children)
// }
routers.push(menu)

})
return routers
}`
最后还是一样的错误
[vue-router] route config "component" for path: index cannot be a string id. Use an actual component instead.

希望能贴一下你的代码,前端的组件与后端字符串替换的部分。有完整demo更好

我是这样写的:

//router/index.js
export const routerMap={
 table:_import('table/index')
}
//通过后台请求的路由表,写法跟原本的一样,需要改的地方是component这里,改成map里面组件对应的key值
[
   {
     path: '/table,
     component: 'table',
     redirect: 'noredirect',
     name: 'table',
    }
]
//store/modules/permission.js
import { constantRouterMap, map } from '@/router/index'
// 将本地routerMap映射到ajax获取到的serverRouterMap;
function generateAsyncRouter(routerMap, serverRouterMap) {
  serverRouterMap.forEach(function (item, index) {
    item.component = routerMap[item.component]
    if(item.children && item.children.length > 0){
      generateAsyncRouter(routerMap, item.children)
    }
  })
  return serverRouterMap;
}
//然后在actions中GenerateRoutes方法合适的地方将后端请求的路由表映射到routerMap,并筛选出可访问的路由,serverRouterMap是我定义的从后台请求路由表的方法
serverRouterMap().then(response => {
          var asyncRouterMap = generateAsyncRouter(routerMap, response.data.serverRouterMap)
          if (roles.indexOf('admin') >= 0) {
            accessedRouters = asyncRouterMap
          } else {
            accessedRouters = filterAsyncRouter(asyncRouterMap, roles)
          }
          commit('SET_ROUTERS', accessedRouters)
          resolve()
        })

卧槽,感谢感谢,成功了

小弟我还是有点迷茫啊,大神们

我也是后台返回导航菜单,但是映射的时候总是报undefined。
这是后台返回的菜单:
{
"code": 20000,
"data": {
"roles": [
{
"path": "/form2",
"component": "Layout",
"redirect": "/form2/index2",
"name": "permission",
"children": [
{
"path": "index2",
"name": "Form2",
"component": "table"
}
]
},
{
"path": "/form3",
"component": "Layout",
"alwaysShow": true,
"redirect": "/form2/index2",
"name": "permission2",
"children": [
{
"path": "index3",
"name": "Form3",
"component": "form"
}
]
},
{
"path": "/form3",
"component": "Layout",
"children": [
{
"path": "index",
"name": "Form",
"component": "form2"
}
]
}
],
"name": "editor",
"avatar": "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif"
}
}

处理数据这里:
GenerateRoutes({ commit }, data) {
return new Promise(resolve => {
const { asyncRouterMap } = data
console.log(data + 'data=============')
console.log(asyncRouterMap)
const accessedRouters = convertRouter(asyncRouterMap)
commit('SET_ROUTERS', accessedRouters)
resolve()
})
}

然后这里:
const { asyncRouterMap } = data
赋值不成功麻烦,不知道是不是数据的问题。

@gaoshijun1993 ,大佬,请问下动态获取路由表信息是在什么地方获取的?

@Danbaoshan请问下您是怎么解决的?

@wlLeblanc 按照5楼大哥的写法就可以实现

@Danbaoshan 请问下我这样做映射怎么就不对?
image左边导航栏有数据,但是进去页面就是空白
image

@gaoshijun1993 可以帮忙解决一下吗?感谢感谢!

我也遇到同样的问题 @wlLeblanc 解决了吗

好厉害,明天我试试

父级 的component 也要做映射!!!@chen-can @wlLeblanc @wd308389182

我是这样写的:

//router/index.js
export const routerMap={
 table:_import('table/index')
}

```
//通过后台请求的路由表,写法跟原本的一样,需要改的地方是component这里,改成map里面组件对应的key值
[
{
path: '/table,
component: 'table',
redirect: 'noredirect',
name: 'table',
}
]


//store/modules/permission.js
import { constantRouterMap, map } from '@/router/index'
// 将本地routerMap映射到ajax获取到的serverRouterMap;
function generateAsyncRouter(routerMap, serverRouterMap) {
serverRouterMap.forEach(function (item, index) {
item.component = routerMap[item.component]
if(item.children && item.children.length > 0){
generateAsyncRouter(routerMap, item.children)
}
})
return serverRouterMap;
}
//然后在actions中GenerateRoutes方法合适的地方将后端请求的路由表映射到routerMap,并筛选出可访问的路由,serverRouterMap是我定义的从后台请求路由表的方法
serverRouterMap().then(response => {
var asyncRouterMap = generateAsyncRouter(routerMap, response.data.serverRouterMap)
if (roles.indexOf('admin') >= 0) {
accessedRouters = asyncRouterMap
} else {
accessedRouters = filterAsyncRouter(asyncRouterMap, roles)
}
commit('SET_ROUTERS', accessedRouters)
resolve()
})
```

为什么我的路由映射不行,解析不出来。component的值是Promise???

GenerateRoutes({commit}, data) {
  return new Promise(resolve => {
    const roles = data.roles;
    let accessedRouters;
    getAccountPower(roles).then(response => {
      console.log('后台获取的路由表', response.data);
      var asyncRouterMap = generateAsyncRouter(routerMap, response.data);
      // console.log('asyncRouterMap',asyncRouterMap);
      if (roles.indexOf('admin') >= 0) {
        accessedRouters = asyncRouterMap
      } else {
        accessedRouters = filterAsyncRouter(asyncRouterMap, roles)
      }
      commit('SET_ROUTERS', accessedRouters)
      resolve();
    });

  })
}

//将本地routeMap映射到ajax获取到的serverRouteMap
function generateAsyncRouter(routerMap, serverRouterMap) {
serverRouterMap.forEach(function (item, index) {
item.component = routerMap[item.component];
console.log('item.component', item.component);
if (item.children && item.children.length > 0) {
generateAsyncRouter(routerMap, item.children)
}
})
return serverRouterMap;
}

@weiving 参考下我前几天的pr的

@weiving 参考下我前几天的pr的

已解决,是我自己代码写错了= =

@Danbaoshan请问下我这样做映射怎么就不对?
图片左边导航栏有数据,但是进去页面就是空白
图片

请问解决了吗,我也遇到同样的问题了.

@gaoshijun1993 请问我应该让后台给什么格式的数据呢,我还是不太懂,是把本地的asyncRouterMap在服务器端寸一份,让服务器给返回当前用户拥有的router是吗

@Danbaoshan请问下我这样做映射怎么就不对?
图片左边导航栏有数据,但是进去页面就是空白
图片

请问解决了吗,我也遇到同样的问题了.

router.addRoutes(newRouter)后需要next({ ...to, replace: true })
参考:https://segmentfault.com/q/1010000015875314

@Danbaoshan 请问下我这样做映射怎么就不对?
image左边导航栏有数据,但是进去页面就是空白
image

router.addRoutes(newRouter)后需要next({ ...to, replace: true })
参考:https://segmentfault.com/q/1010000015875314

293

map进去了点击菜单报找不到模块是怎么回事 啊,路径都是对的

路由表里面的这个component是字符串路径,请求获取后,在本地map到相对应的组件就可以了

大佬我想问你一下,后台返回路由是一股脑全部返回回来吗。还是说针对角色只返回能看到的路由啊;
那部分的一些操作权限 你这边是怎么处理的呢

我是这样写的:

//router/index.js
export const routerMap={
 table:_import('table/index')
}
//通过后台请求的路由表,写法跟原本的一样,需要改的地方是component这里,改成map里面组件对应的key值
[
   {
     path: '/table,
     component: 'table',
     redirect: 'noredirect',
     name: 'table',
    }
]
//store/modules/permission.js
import { constantRouterMap, map } from '@/router/index'
// 将本地routerMap映射到ajax获取到的serverRouterMap;
function generateAsyncRouter(routerMap, serverRouterMap) {
  serverRouterMap.forEach(function (item, index) {
    item.component = routerMap[item.component]
    if(item.children && item.children.length > 0){
      generateAsyncRouter(routerMap, item.children)
    }
  })
  return serverRouterMap;
}
//然后在actions中GenerateRoutes方法合适的地方将后端请求的路由表映射到routerMap,并筛选出可访问的路由,serverRouterMap是我定义的从后台请求路由表的方法
serverRouterMap().then(response => {
          var asyncRouterMap = generateAsyncRouter(routerMap, response.data.serverRouterMap)
          if (roles.indexOf('admin') >= 0) {
            accessedRouters = asyncRouterMap
          } else {
            accessedRouters = filterAsyncRouter(asyncRouterMap, roles)
          }
          commit('SET_ROUTERS', accessedRouters)
          resolve()
        })

大佬,请问而这个动态路由的分支项目有吗?

父级 的component 也要做映射!!!@chen-can @wlLeblanc @wd308389182

是的,父级component也要做映射,还有还得加上循环加上meta,因为菜单栏是根据meta的title来显示菜单的,对吗?

跪求动态权限菜单如何做,如何改动store/modules/permission.js这个文件

后台数据:
data: {id: "04e5a2fe-226a-11eb-acad-005056a6bd8d", userCode: "admin", userName: "admin",…}
buttonInfos: [{resouceCode: "useradd", rosouceName: "新增", resouceIcon: "", resouceUrl: "", resouceSeq: null,…},…]
departmentId: "10caad21-d9eb-4a57-950b-c28395454f68"
departmentName: null
id: "04e5a2fe-226a-11eb-acad-005056a6bd8d"
menuInfos: [,…]
0: {id: "04e5a2fe-226a-11eb-acad-005056a6bd8d", resouceCode: "R0001", rosouceName: "系统管理", parentId: null,…}
childMenus: [{id: "04e5a2fe-226a-11eb-acad-005056a6bd81", resouceCode: "R000101", rosouceName: "用户管理",…},…]
0: {id: "04e5a2fe-226a-11eb-acad-005056a6bd81", resouceCode: "R000101", rosouceName: "用户管理",…}
childMenus: []
id: "04e5a2fe-226a-11eb-acad-005056a6bd81"
parentId: "04e5a2fe-226a-11eb-acad-005056a6bd8d"
resouceCode: "R000101"
resouceIcon: null
resouceSeq: 1
resouceUrl: "/user/index"
rosouceName: "用户管理"
1: {id: "6422c53f-c18a-4981-8ac1-bbdcb7ce2d5e", resouceCode: "R0004", rosouceName: "菜单管理",…}
2: {id: "95e4377e-5435-4152-99b2-b980fc50023c", resouceCode: "j003", rosouceName: "角色管理",…}
3: {id: "52dca850-d9cf-4350-a071-565da024be15", resouceCode: "R0003", rosouceName: "部门管理",…}
id: "04e5a2fe-226a-11eb-acad-005056a6bd8d"
parentId: null
resouceCode: "R0001"
resouceIcon: null
resouceSeq: 1
resouceUrl: null
rosouceName: "系统管理"
roleList: ["R0001"]
userCode: "admin"
userName: "admin"
message: null
status: 200

Was this page helpful?
0 / 5 - 0 ratings