写这篇文章的目的是为了记录两天的成果。。
关于vue权限的参考是从花裤衩
大佬那得到的启发
1、首先声明,阅读此博客需要:
- vuex 基础
- 了解mock
- 了解route/router
- 权限的实现
- 路由守卫
2、讲解一下本项目权限的实现:
权限:动态菜单栏,不同用户能看到的页面是不同的,所以,当用户登陆时,服务端判断该用户的权限,返回该用户的路由表–至于按钮级别的权限,可以用页面权限去实现,或者使用v-if命令实现【注意,前台不可以相信,权限还是要后台判断】
路由:vuex+localStorage实现【刷新重新拉取路由表】
3、实现思路+部分代码【后续代码全部贴出】
a.定义一个未登录可以查看的页面–路由守卫第一层判断
const whiteList = ['/login', '/solution/index',
'/productIntroduction/index',
'/seo/index', '/contactUs/index', '/farm/index', '/404']
// no redirect whitelist 没有重定向白名单
router.beforeEach((to, from, next) => {
//如果含有token值,也就是处于登陆状态
if (getToken()) {
//不允许跳出登陆状态【本系统下规定】
if (whiteList.indexOf(to.path) !== -1) {
next({ path: '/' });
NProgress.done();
}else {
.........................
}
b.因为后台返回的数据是没有经过处理的,所以前台不能直接使用,还需进行一步转换
转换函数如下:递归
function filterAsyncRouter(asyncRouterMap) { //遍历后台传来的路由字符串,转换为组件对象
const accessed = asyncRouterMap.filter(route => {
if (route.component) {
if (route.component === 'LayoutF') {//Layout组件特殊处理【本系统的布局组件】
route.component = LayoutF
} else {
route.component = _import(route.component) //自定的引入组件的方式
}
}
if (route.children && route.children.length) { //递归调用
route.children = filterAsyncRouter(route.children)
}
return true
});
return accessed
}
c.在写本项目时,笔者遇到将经过处理的路由表放入localStorage中,用的时候再取,结果一直遇到陷入死循环的问题,且问题还未解决,大佬路过请指点~~【错误源码见本文尾】
笔者更改方法为每次用户刷新向服务器从新拉取路由表,这样一来,动态修改权限同时也就实现了。
定义一个变量为true,拉取完信息更改其为false,用户刷新则又变为true,这样,我们又多了一个判断条件
//registerRouteFresh定义为true
if (registerRouteFresh) {
//判断vuex中是否含有异步路由表
if(store.getters.asyncRouterMap.length ===0){
//从服务器拉取路由表
store.dispatch('RouteFresh',getToken()).then((data)=>{
//返回空,则强制退出
if(data===''){
quit();
next(`/login?redirect=${to.path}`) // 否则全部重定向到登录页
}else{
//如果vuex中含有异步路由表,将异步路由表转换
GenerateRoutes(store.getters.asyncRou