前言
系统在用了一段时间后,产品经理提出了新建子账号并可配置菜单权限的需求。配置子账号拥有部分菜单权限,并在子账号登录后,在地址栏直接输入本不属于该子账号的页面路由,要求重定向到404页面,即实现拦截。
开始
经过各种查阅资料,决定使用addRoute 动态添加路由。后台在登录后会返回账户菜单,是一个code的str合集,这个code对应每个菜单的code,是前后台约定好的。
步骤如下:
1、router/index.js:定义初始路由constantRoutes 和动态变化的路由DynamicRoutes ;
2、generateRoutes.js:(文件可以放在utils下,我放在了assets下)这个文件定义了generateRoutes方法,动态过滤路由,通过后台返回的code 合集,和DynamicRoutes 作比对,生成需动态添加的路由,然后用 router.addRoute()添加 ;
3、login.vue:在登录后,后台返回了该账户的code合集,调用generateRoutes 方法动态生成导航 ;
4、router/index.js:
① 路由守卫 ;
② router.onReady() 函数里写异步操作,用于已登录状态下刷新页面获取code合集并生成动态导航 ;
代码
router/index.js
//静态路由
const constantRoutes = [
{
{
path: '/login',
name: 'login',
component: (resolve) => require(['../views/admin/login.vue'], resolve),
meta:{
title:'登录',needLogin:false,noLeft:true}
}];
//动态路由
export const DynamicRoutes = [
{
// 首页
path: '/index/',
name: 'index',
component:(resolve) => require(['../views/index.vue'], resolve),
meta:{
title:'首页',head:true,code:'v1'}
},
.
.
.
] ;
const createRouter = () => new Router({
mode: 'history',
base: 'cs',
routes: constantRoutes
})
const router = createRouter();
// 路由守卫
router.beforeEach((to, from, next)=>{
if(to.matched.some(res=>('needLogin' in res.meta) && (res.meta.needLogin == false))){
//不需要登录的页面
if((to.path == '/login') && (window.sessionStorage['user_token'])){
//登录页面 且 有token(说明登录过)
next('/index');
}else{
next();
}
}else{
//需要登录
if(window.sessionStorage['user_token']){
//有token,登录状态下
next()
}else{
//无token,跳转回宣传首页
next({
path: '/login'});
}
}
});
//异步请求写在这里面
router.onReady(() => {
console.group('%c%s', 'color:red', `${
new Date().getTime()} 路由完成初始导航----------`)
console.log('添加前-所有活跃的路由记录列表', router.getRoutes())
if(window.sessionStorage['user_token']){
//已登录
userApi.getUserInfo().then(response => {
if (response.code == 200) {
let data = response.data;
let accountType = data.accountType;//账户类型
let authCodes = data.authCodes;//code合集
generateRoutes(accountType,authCodes);
console.log('添加后-所有活跃的路由记录列表', router.getRoutes())
console.groupEnd()
}
})
}
});
// 重置路由
export function resetRouter () {
const newRouter = createRouter()
router.matcher = newRouter.matcher
}
export default router;
generateRoutes.js
import router,{
DynamicRoutes} from '@/router/index'
//匹配动态生成导航
export function generateRoutes (accountType,authCodes) {
//1.过滤需要的动态路由
let realRoutes = [];
if(accountType == 1){
//主账号,有所有路由
realRoutes = DynamicRoutes;
}else{
//子账号,根据authCodes过滤
DynamicRoutes.forEach(item=>{
if(!('children' in item)){
if(authCodes.indexOf(item.meta.code) != '-1'){
realRoutes.push(item);
}
}else{
let arr = [];
item.children.forEach(item1=>{
if(authCodes.indexOf(item1.meta.code) != '-1'){
arr.push(item1);
}
})
if(arr.length > 0){
let item2 = Object.assign({
},item);
item2.children = arr;
realRoutes.push(item2);
}
}
})
}
//2.添加路由
realRoutes.forEach(route => {
router.addRoute(route)
})
//3、添加输入其他路由时需要重定向的路由
router.addRoute({
path: '*',
redirect: '/userCenter/myAccount'
});
}
login.vue
登录成功后,调用生成导航的方法
import {
generateRoutes } from '@/assets/js/func/generateRoutes.js'
export default {
name: 'login',
data(){
login() {
api.login(params).then(res=>{
this.user=res.data;
let accountType = this.user.accountType;
let authCodes = this.user.authCodes;
//1.生成导航
generateRoutes(accountType,authCodes);
.
.
.
})
}
}
结束
在此记录问题,如有需要修改的地方,还请不吝赐教。文章借鉴:vue-router的addRoute方法实现权限控制