Closed wuzechuan closed 7 years ago
那就不再路由里设置权限信息
{path: '/table', name: '表格综合实例',icon:'ios-paper',component: _import('Table'),meta: { role: ['admin'] }},
其中的
meta: { role: ['admin'] }
就是配置的权限信息,只要不加这个就不会牵涉到权限问题
我后端登陆接口里没有返回roles的字段,返回的字典是result,我设了一个个人信息的字段info,还有一个专门存token的字段 在login.js文件处理beforeeach的方法里面
store.dispatch('GetInfo').then(res => { // 拉取user_info
const roles = res.data.role
store.dispatch('GenerateRoutes', { roles }).then(() => { // 生成可访问的路由表
router.addRoutes(store.getters.addRouters) // 动态添加可访问路由表
next({ ...to }) // hack方法 确保addRoutes已完成
})
}).catch(() => {
store.dispatch('FedLogOut').then(() => {
next({ path: '/login' })
const roles = res.data.role 这里应该是const roles = res.result.info的是吧 如果赋值给store.dispatch('GenerateRoutes', { roles }).then(() 这里权限校验的话,会报 Unhandled promise rejection TypeError: Cannot read property 'indexOf' of undefined(…) 也就是permission文件里的(roles.indexOf('admin' ,校验这个)
GenerateRoutes({ commit }, data) {
return new Promise(resolve => {
const { roles } = data
let accessedRouters
if (roles.indexOf('admin') >= 0) {
accessedRouters = asyncRouterMap
} else {
accessedRouters = filterAsyncRouter(asyncRouterMap, roles)
}
commit('SET_ROUTERS', accessedRouters);
resolve();
这里面需要有个admin的值,如果只屏蔽meta['admin']的话,应该还是不够的吧? 我的页面现在是登录了,但是还是在登录页面,因为出现了那个错误
如果你已经移除了mock.js,请求外部api的话,还需要修改src/store/modules/user.js。
如果得不到response, Promise reject了,就登录失败了
这样是最简便的,不请求后端,直接设置cookies为admin
那么这样一来就不是存的后端给的token了吧,可以先屏蔽那段if (roles.indexOf('admin') 这个判断不?
token的作用是要判断是否登录,看你的意思是你需要登录但是不需要权限。 不需要权限的话也可以直接修改 src/login.js 如果登录,直接next下个路由,如果没有,就跳到登录
// register global progress.
const whiteList = ['/login', '/authredirect']// 不重定向白名单
router.beforeEach((to, from, next) => {
NProgress.start() // 开启Progress
if (store.getters.token) { // 判断是否有token
if (to.path === '/login') {
next({ path: '/' })
} else {
next();
}
} else {
if (whiteList.indexOf(to.path) !== -1) { // 在免登录白名单,直接进入
next()
} else {
next('/login') // 否则全部重定向到登录页
NProgress.done() // 在hash模式下 改变手动改变hash 重定向回来 不会触发afterEach 暂时hack方案 ps:history模式下无问题,可删除该行!
}
}
})
@herozhou 但是登陆进来后,侧边栏asyncRouterMap 的好像没有加载出来,是把url都放到constantRouterMap这里?
不好意思把侧边栏给忘了
const whiteList = ['/login', '/authredirect']// 不重定向白名单
router.beforeEach((to, from, next) => {
NProgress.start() // 开启Progress
if (store.getters.token) { // 判断是否有token
if (to.path === '/login') {
next({ path: '/' })
} else {
// 这个要加上。生成侧边栏
store.dispatch('getNowRoutes', to);
next();
}
} else {
if (whiteList.indexOf(to.path) !== -1) { // 在免登录白名单,直接进入
next()
} else {
next('/login') // 否则全部重定向到登录页
NProgress.done() // 在hash模式下 改变手动改变hash 重定向回来 不会触发afterEach 暂时hack方案 ps:history模式下无问题,可删除该行!
}
}
})
还有侧边栏是从src/store/modules/permission.js里获取的,这里也需要改
路由的话就把asyncRouterMap的路由对象放到constantRouterMap里
@herozhou 我按照你的修改后,页面还是没加载侧边栏,然后有个报错的提示:
es6.promise.js?903b:103 Unhandled promise rejection TypeError: Cannot read property 'forEach' of undefined
at SET_NOW_ROUTERS (eval at <anonymous> (http://localhost:9528/app.js:1843:1), <anonymous>:79:23)
at wrappedMutationHandler (eval at <anonymous> (http://localhost:9528/app.js:1108:1), <anonymous>:596:5)
at commitIterator (eval at <anonymous> (http://localhost:9528/app.js:1108:1), <anonymous>:320:7)
at Array.forEach (native)
at eval (eval at <anonymous> (http://localhost:9528/app.js:1108:1), <anonymous>:319:11)
at Store._withCommit (eval at <anonymous> (http://localhost:9528/app.js:1108:1), <anonymous>:407:3)
at Store.commit (eval at <anonymous> (http://localhost:9528/app.js:1108:1), <anonymous>:318:8)
at boundCommit (eval at <anonymous> (http://localhost:9528/app.js:1108:1), <anonymous>:274:19)
at eval (eval at <anonymous> (http://localhost:9528/app.js:1843:1), <anonymous>:110:9)
at new Promise (eval at <anonymous> (http://localhost:9528/app.js:2080:1), <anonymous>:177:7)
我不知道你是怎么写的,我这边是没问题,我先把代码都贴出啦你比对一下,重点是路由的代码,一定要有children,不能写空的父元素。 src/router/index.js
import Vue from 'vue';
import Router from 'vue-router';
const _import = require('./_import_' + process.env.NODE_ENV);
import Full from '@/containers/Full'
import Full2 from '@/containers/Full2'
import Buttons from '@/views/components/Buttons'
// Views - Pages
import Page404 from '@/views/errorPages/Page404'
import Page500 from '@/views/errorPages/Page500'
/* login */
const Login = _import('login/index');
Vue.use(Router);
export const constantRouterMap = [
{ path: '/login', component: Login, hidden: true },
{path: '/pages',redirect: '/pages/p404', name: 'Pages',
component: {
render (c) { return c('router-view') }
// Full,
},
children: [{path: '404', name: 'Page404', component: _import('errorPages/Page404') },
{path: '500',name: 'Page500',component: _import('errorPages/Page404')},
]
},
{
path: '/',
redirect: '/dashboard',
name: '首页',
component: Full,
hidden:false,
children: [
{path: '/dashboard',name: 'Dashboard',icon:'speedometer',component: _import('Dashboard')},
{path: '/introduction',name: '介绍',icon:'thumbsup',component: _import('Introduction')},
{path: '/components',name: 'component组件',redirect: '/components/buttons',icon:'bookmark',
component: {render (c) { return c('router-view') }},
children: [ {path: 'buttons',name: 'Buttons按钮',icon:'social-youtube',component: _import('components/Buttons'), hidden:false, },
{path: 'hoverbuttons',name: '悬停特效按钮',icon:'wand',component: _import('components/HoverButtons')},
{path: 'alert',name: 'Alert警告提示',icon:'alert',component: _import('components/Alert')},
{path: 'card',name: 'Card卡片',icon:'ios-browsers-outline',component: _import('components/Card')},
{path: 'datepicker',name: 'DatePicker',icon:'ios-calendar-outline',component: _import('components/DatePicker')},
{path: 'form',name: 'Form表单',icon:'ios-list-outline',component: _import('components/Form')},
{path: 'modal',name: 'Modal对话框',icon:'ios-chatbubble-outline',component: _import('components/Modal')},
{path: 'select',name: 'Select选择器',icon:'ios-arrow-down',component: _import('components/Select')},
{path: 'spin',name: 'Spin加载中',icon:'load-d ',component: _import('components/Spin')},
{path: 'steps',name: 'Steps步骤条',icon:'ios-checkmark-outline',component: _import('components/Steps')},
{path: 'timeline',name: 'Timeline时间轴',icon:'android-more-vertical',component: _import('components/Timeline')},
{path: 'transfer',name: 'Transfer穿梭框',icon:'ios-pause-outline',component: _import('components/Transfer')},
{path: 'timepicker',name: 'Timepicker',icon:'ios-clock-outline',component: _import('components/Timepicker')},
{path: 'upload',name: 'Upload上传',icon:'ios-cloud-upload-outline',component: _import('components/Upload')},
]
},
{path: '/charts',name: 'echart图表',redirect: '/charts/shopchart',icon:'pie-graph',
component: {render (c) { return c('router-view') }},
children: [ {path: 'shopchart',name: '商场统计图表',icon:'stats-bars',component: _import('charts/ShopChart'), hidden:false, },
{path: 'radarchart',name: '雷达图',icon:'arrow-graph-up-right',component: _import('charts/RadarChart')},
{path: 'cakechart',name: '蛋糕销量图表',icon:'ios-analytics',component: _import('charts/CakeChart')}
]
},
{path: '/table', name: '表格综合实例',icon:'ios-paper',component: _import('Table'),meta: { role: ['admin'] }},
{path: '/jsontree', name: 'JSON视图',icon:'merge',component: _import('JsonTree')},
{path: '/tabledetail/:id',name: 'TableDetail', hidden:true, component: _import('TableDetail')},
{path: '/tinymce',name: 'Tinymce编辑器',icon:"android-document",component: _import('Tinymce')},
{path: '/markdown',name: 'Markdown',icon:"android-list",component: _import('Markdown')},
]
},
{
path: '/home1',
redirect: '/home1/introduction',
name: 'home',
component: Full2,
hidden:false,
children: [
{path: '/home1/dashboard',name: 'Dashboard2',icon:'speedometer',component: _import('Dashboard2')},
{path: '/home1/introduction',name: '介绍2',icon:'thumbsup',component: _import('Introduction')},
]
},
{ path: '*', redirect: '/pages/404', hidden: true }
]
export default new Router({
mode: 'hash',
linkActiveClass: 'open active',
scrollBehavior: () => ({ y: 0 }),
routes: constantRouterMap
});
export const asyncRouterMap = [
];
src/srore/modules/permission.js
import { asyncRouterMap, constantRouterMap } from 'src/router';
/**
* 通过meta.role判断是否与当前用户权限匹配
* @param roles
* @param route
*/
function hasPermission(roles, route) {
if (route.meta && route.meta.role) {
return roles.some(role => route.meta.role.indexOf(role) >= 0)
} else {
return true
}
}
/**
* 递归过滤异步路由表,返回符合用户角色权限的路由表
* @param asyncRouterMap
* @param roles
*/
function filterAsyncRouter(asyncRouterMap, roles) {
const accessedRouters = asyncRouterMap.filter(route => {
if (hasPermission(roles, route)) {
if (route.children && route.children.length) {
route.children = filterAsyncRouter(route.children, roles)
}
return true
}
return false
})
return accessedRouters
}
function getNowRouter(asyncRouterMap, to) {
return asyncRouterMap.some(route => {
if(route.path===to.path) {
return true;
}
else if (route.children && route.children.length) { //如果有孩子就遍历孩子
return getNowRouter(route.children, to)
}
})
}
const permission = {
state: {
routers: constantRouterMap,
addRouters: constantRouterMap,
siderbar_routers:constantRouterMap,
},
mutations: {
SET_ROUTERS: (state, routers) => {
state.addRouters = routers;
state.routers = constantRouterMap.concat(routers);
// state.routers.forEach(function(e){
// if(e.name==="首页"){
// state.siderbar_routers=e;
// }
// })
},
SET_NOW_ROUTERS: (state, to) => {
//你是在这里报错的,要不是路由没有配置正确,要不就是这个函数的问题
// 递归访问 accessedRouters,找到包含to 的那个路由对象,设置给siderbar_routers
console.log(state.addRouters)
state.addRouters.forEach(e => {
if(e.children&& e.children.length ){
if( getNowRouter(e.children,to)===true)
state.siderbar_routers=e;
}
})
}
},
actions: {
GenerateRoutes({ commit }, data) {
return new Promise(resolve => {
const { roles } = data
let accessedRouters
if (roles.indexOf('admin') >= 0) {
accessedRouters = asyncRouterMap
} else {
accessedRouters = filterAsyncRouter(asyncRouterMap, roles)
}
commit('SET_ROUTERS', accessedRouters);
resolve();
})
},
getNowRoutes({ commit }, data) {
return new Promise(resolve => {
//data => to
commit('SET_NOW_ROUTERS', data);
resolve();
})
},
},
};
export default permission;
如果还是有问题把你邮箱发给我,我把代码发给你
你先试下这样行不行
export const constantRouterMap = [
{ path: '/login', component: Login, hidden: true },
{ path: '/404', component: Err404, hidden: true },
{
path: '/release',
component: Layout,
redirect: 'noredirect',
name: '发布管理',
icon: 'zonghe',
children: [
{ path: '/release/index', component: _import('release/releaselist'), name: '发布列表' },
{ path: '/release/flowlist', component: _import('release/flowlist'), name: '审批流列表' }
]
},
{ path: '*', redirect: '/404', hidden: true },
//{ path: '/approvetable/rid/:id', component: _import('release/singlerelease'), hidden: true },
{
path: '/',
component: Layout,
redirect: '/introduction',
name: 'Home',
hidden: true,
children: [{ path: '/introduction', component: introduction }]
}
]
@herozhou 还是报那个错误
方便把你代码发到我邮箱吗?
@herozhou ok,发到你邮箱了
你好,我这边功能是想先实现基础功能,还没有涉及权限的部分,如何屏蔽权限校验的部分,账号一登陆就可以直接展示所有东西呢?