Open hiddenlong opened 4 years ago
点击后台菜单后,后台返回路由数据,but 你的路由 没有侧边和顶部栏的原因 是在 component:Layout里面的Layout是一个变量,而你的返回的是一个常量,解析的时候 会 router = [{ path: '', hidden: true, component: Layout,......}] Layout 会预先 去 解析,但是路由解析不了这个 所以导致成未知的 从而进入了404
@zhoupeihuang 再贴代码上来,帮忙看看分析分析怎么解决?
明天吧,下班了
---原始邮件--- 发件人: "hiddenlong"<notifications@github.com> 发送时间: 2020年6月30日(周二) 晚上8:12 收件人: "PanJiaChen/vue-element-admin"<vue-element-admin@noreply.github.com>; 抄送: "Mention"<mention@noreply.github.com>;"zhoupeihuang"<625506370@qq.com>; 主题: Re: [PanJiaChen/vue-element-admin] 动态路由成功从后台获取菜单,但点击后转向404页面 (#3143)
@zhoupeihuang 再贴代码上来,帮忙看看分析分析怎么解决?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.
1、如果静态路由里配置了404,那么会跳转到404页面 2、如果删除静态路由的404配置,整个页面就会跳转到一个空白的页面(左边菜单也没了) NO1:静态路由删除 path:"*" == 404 否则的确会所有都是404 NO2:条件空白页是 页面装载时候 没加入 左侧菜单,此处叫做Layout组件集合 你可以 静态路由配置加入roles and hidden:true 这个是所有静态都是加入这个,相当于一个完整的路由权限表 写在前端 然后后台获取的路由权限 routerList 再执行一遍filterAsyncRoutes 具体 https://juejin.im/post/591aa14f570c35006961acac 从权限篇哪里看 wechat :xiaopei727771
No2就是我现在的解决方案,缺陷在于菜单增加后,前端也必须在静态菜单上添加,感觉不完美...我看见有人直接从后台读取菜单,并显示的,但按照他们那种方式,还是始终解决不了,动态创建layout为空的问题...
`/**
@param routes
*/
export function generaMenu(routes, data) {
data.forEach(item => {
// alert(JSON.stringify(item))
const menu = {
path: item.path === '#' ? item.id + 'key' : item.path,
component: item.component === '#' ? Layout : () => import(@/views${item.component}
),
hidden: item.hidden,
redirect: item.redirect,
children: [],
name: 'menu' + item.id,
meta: item.meta
// meta: { title: item.name, id: item.id, roles: ['admin'] }
}
if (item.children) { generaMenu(menu.children, item.children) } routes.push(menu) }) }` 我觉得应该是这个地方出了问题。
你的addrouters 呢
实现的时候 别忘记告诉我 感激
625506370@qq.com
发件人: hiddenlong
发送时间: 2020-07-01 10:59
收件人: PanJiaChen/vue-element-admin
抄送: zhoupeihuang; Mention
主题: Re: [PanJiaChen/vue-element-admin] 动态路由成功从后台获取菜单,但点击后转向404页面 (#3143)
No2就是我现在的解决方案,缺陷在于菜单增加后,前端也必须在静态菜单上添加,感觉不完美...我看见有人直接从后台读取菜单,并显示的,但按照他们那种方式,还是始终解决不了,动态创建layout为空的问题...
/** 后台查询的菜单数据拼装成路由格式的数据 @param routes */ export function generaMenu(routes, data) { data.forEach(item => { // alert(JSON.stringify(item)) const menu = { path: item.path === '#' ? item.id + 'key' : item.path, component: item.component === '#' ? Layout : () => import(@/views${item.component}), hidden: item.hidden, redirect: item.redirect, children: [], name: 'menu' + item.id, meta: item.meta // meta: { title: item.name, id: item.id, roles: ['admin'] } } if (item.children) { generaMenu(menu.children, item.children) } routes.push(menu) }) }
我觉得应该是这个地方出了问题。
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or unsubscribe.
1、src/permission.js 关键:store.dispatch('permission/generateRoutes', roles)
router.beforeEach(async(to, from, next) => {
......
try {
// get user info
// note: roles must be a object array! such as: ['admin'] or ,['developer','editor']
const { roles } = await store.dispatch('user/getInfo')
// generate accessible routes map based on roles
const accessRoutes = await store.dispatch('permission/generateRoutes', roles)
// dynamically add accessible routes
router.addRoutes(accessRoutes)
// hack method to ensure that addRoutes is complete
// set the replace: true, so the navigation will not leave a history record
next({ ...to, replace: true })
} catch (error) {
// remove token and go to login page to re-login
await store.dispatch('user/resetToken')
Message.error(error || 'Has Error')
next(`/login?redirect=${to.path}`)
NProgress.done()
}
......
})
2.store/permission.js 关键:generateRoutes,generaMenu
generateRoutes({ commit }, roles) {
return new Promise(resolve => {
const loadMenuData = []
// 先查询后台并返回左侧菜单数据并把数据添加到路由
getAuthMenu(state.token).then(response => {
let data = response
if (response.code !== 20000) {
alert(JSON.stringify('菜单数据加载异常'))
// throw new Error('菜单数据加载异常')
} else {
data = response.data
Object.assign(loadMenuData, data)
const tempAsyncRoutes = Object.assign([], asyncRoutes)
// tempAsyncRoutes = asyncRoutes
generaMenu(tempAsyncRoutes, loadMenuData)
let accessedRoutes
if (roles.includes('admin')) {
// alert(JSON.stringify(asyncRoutes))
accessedRoutes = tempAsyncRoutes || []
} else {
accessedRoutes = filterAsyncRoutes(tempAsyncRoutes, roles)
}
commit('SET_ROUTES', accessedRoutes)
resolve(accessedRoutes)
}
// generaMenu(asyncRoutes, data)
}).catch(error => {
console.log(error)
})
})
}
export function generaMenu(routes, data) {
data.forEach(item => {
// alert(JSON.stringify(item))
const menu = {
path: item.path === '#' ? item.id + '_key' : item.path,
component: item.component === '#' ? Layout : () => import(`@/views${item.component}`),
hidden: item.hidden,
redirect: item.redirect,
children: [],
name: 'menu_' + item.id,
meta: item.meta
// meta: { title: item.name, id: item.id, roles: ['admin'] }
}
if (item.children) {
generaMenu(menu.children, item.children)
}
routes.push(menu)
})
}
目前问题还为解决...等项目完成之后再回头来看看这个问题吧
我们项目中用户拥有不同角色,角色可以动态配置不同的权限,API获取用户权限列表进而展示不同的菜单,同样遇到这个问题,除了上面提到的No2,请问兄弟还有什么更好的解决方案吗?
我困惑了3个小时后,莫名奇妙解决了这个问题。 要解决问题要有逆向思维,不要想着后端获取路由-》拼接路由route-》add到左侧菜单这条路。 要先把所有可能的路由都放进去,然后再把菜单显示filter出去。也就是在export const asyncRoutes 这个里面,把所有可能的路由配置上。 然后再filterAsyncRoutes 这里面去filter。 如果asyncRoutes 原来没有这个路由,永远是404
可能和nodejs的便宜环境有关系,现在使用了另外一个基于该项目的开源项目。已经没有这个问题了。
已从后台读取菜单,成功在前台显示了 但点击菜单后,转向有问题
1、如果静态路由里配置了404,那么会跳转到404页面 2、如果删除静态路由的404配置,整个页面就会跳转到一个空白的页面(左边菜单也没了)
努力的经过: 1、把从后台某个菜单写成前台静态的菜单,然后与后台动态菜单进行对比 对比如下图: 上图是前台静态的menu,在调试的时候看见的数据
上图是后台动态菜单,加载到routers之后的数据
2、对比了下动态加载的组件,如图下图: 静态菜单是可以加载成功的,转向正常;(上图的per/perm是静态页面的路由)
点击后台菜单后,per/setper并没有动态加载出资源页面 很困惑.... 本来想追踪menu的点击事件,但不晓得咋入手了... 问题到这儿,不知道该怎么进行下去了。 不知道哪位大佬能帮忙看看问题?
注意:前台的页面是实际存在的...与前台静态写的menu我从后台读取出来,同样显示404。404这个问题和后台无关,还没到后台的部分。