路由权限的实现,基本原理是添加一个全局的前置钩子函数router.beforeEach(hook),这个函数会在路由切
换开始时调用,即在用户登录时,获取用户权限表,通过权限表与白名单对比,利用addRoutes()方法动
态挂在路由,即实现权限控制。下面我将对至二级路由的权限控制的思路即重要代码分布介绍:
我大体介绍一下本人项目中需要用到控制的点:平台中有三种登录身份:主账号,子账号,运营者账号;对子账号和运营者账号
分别显示不同功能页面。项目开发之初,利用v-show写的死页面,后期为了实现主账号可动态控制子账号与运营者账号权限页
面,故而利用钩子函数实现控制。不同身份的路由权限表可以是以下格式:
// 子账号:[
// {name:'首页',path:'/index'},
// {name:'首页-异常设备',path:'/index/home2'},
// ]
// 运营者账户:[
// {name:'首页',path:'/index'},
// {name:'首页-收益看板',path:'/index/home1'},
// {name:'首页-异常设备',path:'/index/home2'},
// ]
具体格式可在学习完之后,自己定义;
第一步:设置router–index.js设置白名单(即不分权限都要显示的组件路由)和所有需要区别挂载的路由
大体格式如下:
1》引入
import Vue from 'vue'
import Router from 'vue-router'
const inner = () =>
import ('@/components/inner.vue');
const user = () =>
import ('@/components/user.vue'); //登录注册
const loginandregister = ()=>
import ('@/user/loginandregister.vue'); //登录注册 const forgetkey = () =>
import ('@/user/forgetkey.vue'); //忘记密码
const index = () =>
import ('@/views/index.vue'); //首页
const home1 = () =>
import ('@/index/home1.vue'); //首页--收益看板
const home2 = () =>
import ('@/index/home2.vue'); //首页--设备异常
Vue.use(Router)
2》设置白名单
export const constantRouterMap = [
//用户中心========
{
path: '/user',
alias: '/',
name: 'user',
component: user,
children: [{ //登录注册
path: 'loginandregister',
alias: '/',
name: 'loginandregister',
component: loginandregister,
},
{//忘记密码=======
path: 'forgetkey',
alias: '/',
name: 'forgetkey',
component: forgetkey,
},
{
path: '/jump',
name: 'jump',
component: jump,
alias: '/',
},
{
path: '/inner',
name: 'inner',
component: inner,
},
]
3》动态需要根据权限加载的路由表
export const asyncRouterMap = [{
name: "inner",
path: "/inner",
component: inner,
children: [ // 首页=========================
{
path: '/index',
name: '/index',
cname: '首页',
component: index,
children: [],
mate: true,
},
{
path: '/home1',
name: '/index/home1',
component: home1,
cname: '收益看板',
},
{
path: '/home2',
name: '/index/home2',
component: home2,
cname: '设备异常',
},
]
}
4》实例化vue的时候只挂载constantRouter
export default new Router({
mode: 'history',
routes: constantRouterMap
});
第二步:获取权限表
用户登录时获取权限表,并存于localStorage中(roleinfo)
第三步:在mian.js中添加钩子函数
1》首先引入vuex和路由文件index.js
import Vuex from "vuex"
import store from "./vuex/store"
import { constantRouterMap, asyncRouterMap } from '@/router'
2》编写钩子函数逻辑
router.beforeEach((to, from, next) => {
let token =***; //获取登陆时的token,
let userid = ***;//获取登陆时用户的id,
let localrole = localStorage.getItem('role'); //
let localroleinfo = JSON.parse(localStorage.getItem('roleinfo')); //获取本地路由权限信息
if (!token || !localrole || !localroleinfo || !userid) { //以上四种缺少一样则退回登陆页面,此步骤确保本地存储里是有路由权限表的
if (to.path == '/loginandregister') { //若是主动跳至登录页,则执行
next();
} else { //若是跳到其它页面,则返回登录页面
next('/loginandregister')
}
}
//,此处我在vuex中储存权限表的变量是getRoles , getRolesinfo
if (!store.getters.getRoles || from.path == '/loginandregister') { //如果VUEX里没有路由权限信息,或者是由登录页面跳转而来
store.dispatch('setRoles', localrole).then(() => { //dispatch():查找store所有父级,直到找到要找的父组件,并触发指定事件,(此处触发保存信息至VUEX事件,set...)查找setroles,并将localrole的值赋给它
store.dispatch('setRolesinfo', localroleinfo).then(() => {}) //给setrolesinfo赋值localroleinfo
})
const inner = () =>
import ('@/components/inner.vue');
let ctouter = [ //此处拉出需要权限判断的全部子路由的公共父级,即index.js中的asyncRouterMap
{
name: "inner",
path: "/inner",
component: inner,
children: []
}
]
let newa = asyncRouterMap[0].children;
console.log('first', newa)
let newarr = [];
for (let i = 0; i < newa.length; i++) { //循环需要权限的总路由表
for (let y in localroleinfo) { //循环获得的权限路由表
if (newa[i].name == localroleinfo[y]) {//这一步是从后台获取的路由表与asyncRouterMap比对
newarr.push(newa[i]) //先得出完整的权限路由,但此时未区分父级子集
}
}
}
//以下步骤用来区分父级子集,具体逻辑可自行设计
let firstarr = [];
for (let v = 0; v < newarr.length; v++) { //得到一级路由
if (newarr[v].mate) {
firstarr.push(newarr[v]);
newarr.splice(v, 1, '00')
}
}
for (let q = 0; q < newarr.length; q++) {
for (let w = 0; w < firstarr.length; w++) {
let qwe = new RegExp(firstarr[w].path);
if (qwe.test(newarr[q].name)) {
firstarr[w].children.push(newarr[q]);
newarr.splice(q, 1, '00')
}
}
}
ctouter[0].children = firstarr;
store.dispatch('setSrouter', ctouter).then(() => {
router.addRoutes(ctouter) //vue api ---- addRouter ---- 动态挂载路由,即可以进入的路由
})
}
next()
});
(个人整理使用的感觉比较简单的权限控制方法,直接比对,如果有错误,欢迎指出)