使用VueRouter的addRoutes方法实现动态添加用户的权限路由


Posted in Javascript onJune 03, 2019

最近做vue 单页项目涉及到多角色用户权限问题,不同的角色用户拥有不同的功能权限, 不同的功能权限对应的不同的页面

git: https://github.com/pch1024/dynamicRouter

举个例子:
  角色A =>功能1
     =>功能2
     =>功能3
     
  角色B =>功能1
     =>功能4
     =>功能5

第1步 定义默认路由和动态路由

//动态路由(所有角色的都在这里,我们都做好组件页面了所以我们一定有这个,防君子不防小人)
export const dynamicRouter = [
  { path: '/b', name: 'b', component: pageB },
  { path: '/c', name: 'c', component: pageC },
];

//默认路由(无需登录就可以使用)
const routes = [
  { path: '/', redirect: '/login' },
  { path: '/login', component: pageLogin},
  { path: '/404', component: page404},
  { path: '*', redirect: '/404' },
];

const router = new VueRouter({
  mode: 'history',
  routes, // (缩写) 相当于 routes: routes
});

第2步 登录获取权限规则

当然,登录还要获取token、用户信息等,我们暂时不关注,我们的权限规则需要在多处使用所以我们将它存到vuex里

// vue 组件
<li @click="login(['b'])">
 模拟用户1登录,权限['b'],跳转到页面B
</li>
<li @click="login(['c'])">
 模拟用户2登录,权限['c'],跳转到页面B,(用户2没有页面B权限,强行进入会gun去页面404)
</li>
// 登录模块---------------------------------------------------------
import { mapActions } from "vuex";
export default {
 methods: {
  ...mapActions([
   "set_roleRouterRules"
  ]),
  login(roleRouterRules) {
   // 登录成功,vuex 存储角色路由
   this.set_roleRouterRules(roleRouterRules);
   // 跳转到动态注册B
   this.$router.replace({ path: "/b" });
  }
 }
};

// vuex 对应功能实现-----------------------------------------------
// 引入第1步 定义的dynamicRouter 
import { dynamicRouter } from './router';
// 私有变量
state: {
  isAddRoutes: false,
  // 后端返回的原始数据默认存到 localStorage,每次初始化取出来
  roleRouterRules: JSON.parse(localStorage.getItem('roleRouterRules')),
},
// 公共变量 => 派生私有变量
getters: {
  isAddRoutes: state => state.isAddRoutes,
  // 根据 roleRouterRules 生成当前角色的动态路由配置数据(addRoutes方法可以直接使用的路由数组)
  roleRouter: state => {
    if (state.roleRouterRules) {
      return dynamicRouter.filter(
        router => state.roleRouterRules.indexOf(router.name) >= 0,
      );
    } else return null;
  },
},
// 私有方法(同步) => 改变静态变量
mutations: {
  set_isAddRoutes: (state, data) => (state.isAddRoutes = data), // payload: true/false
  set_roleRouterRules: (state, data) => (state.roleRouterRules = data), // payload: true/false
},
// 公共方法(可异步)=> 调用私有方法
actions: {
  set_isAddRoutes({ commit }, data) {
    commit('set_isAddRoutes', data);
  },
  set_roleRouterRules({ commit }, data) {
    // 保存到vuex
    commit('set_roleRouterRules', data);
    // 保存到 localStorage,当用户强制刷新浏览器时我们要使用这一份数据初始化 state.roleRouterRules
    localStorage.setItem('roleRouterRules', JSON.stringify(data));
  },
}

第3步 登录成功跳转权限页面(核心)

基本思路:

  • 所有的路由跳转都要做鉴权,
  • 不是动态路由(也就是默认路由)直接放过,
  • 是动态路由(也就是还未创建的,强行进入会被重定向到404,但依然可以在to.redirectedFrom获取到用户希望进去的路由),检查前端是否有路由权限规则数据
    • 没有,让他去登录页
    • 有,就根据 roleRouterRules 生成当前角色的动态路由配置数据并addRoutes添加到真实router,此时通过let path = to.redirectedFrom || to.path; 和 next(path); 再走一遍鉴权(这一次真实router上有它就进页面,还没有就代表这个用户没有这个页面访问权限gun去404)

注意事项:

  • addRoutes() 方法一个用户只能使用一次,所以要加一个状态值isAddRoutes到vuex里,每次用户进动态路由时检查 addRoutes 使用过没有
  • next() 方法没有参数会直接放行,有参数(例如 next({path:'/404'})) 放行后会再次进入router.beforeEach,一不小心就是死循环
import vuex from './vuex';
router.beforeEach((to, from, next) => {
  let path = to.redirectedFrom || to.path;
  // 白名单 放行
  if (whiteList.indexOf(path) >= 0) return next();
  // 黑名单
  if (!vuex.getters.roleRouter) return next({ path: '/login' });
  if (!vuex.getters.isAddRoutes) {
    console.log('path未注册,存在角色路由,立即注册尝试匹配');
    router.addRoutes(vuex.getters.roleRouter);
    vuex.dispatch('set_isAddRoutes', true);
    next(path);
  } else {
    console.log('已注册过动态路由,尝试匹配');
    next();
  }
});

第4步 切换不同角色用户

此处有坑, Vue Router 只提供了 addRoutes ,却没有删除和替换方法,所以只能通过强刷新浏览器来重置 Vue Router,先清空localStorage,在刷新时,初始化的Vue Router只有默认路由,用户只能去登录页了

还有一种方法我没看懂,感兴趣可以查看:https://github.com/vuejs/vue-router/issues/1234

exit() {
 localStorage.clear();
 window.location.reload();
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jquery+json实现的搜索加分页效果
Mar 31 Javascript
jQuery中RadioButtonList的功能及用法实例介绍
Aug 23 Javascript
使用jQuery快速解决input中placeholder值在ie中无法支持的问题
Jan 02 Javascript
JS对话框_JS模态对话框showModalDialog用法总结
Jan 11 Javascript
javascript中判断json的方法总结
Aug 27 Javascript
javascript手风琴下拉菜单实现代码
Nov 12 Javascript
js canvas仿支付宝芝麻信用分仪表盘
Nov 16 Javascript
JS实现HTML标签转义及反转义
Apr 14 Javascript
jquery实现拖动效果(代码分享)
Jan 25 Javascript
vue 路由嵌套高亮问题的解决方法
May 17 Javascript
JS div匀速移动动画与变速移动动画代码实例
Mar 26 Javascript
Element实现动态表格的示例代码
Aug 02 Javascript
使用watch在微信小程序中实现全局状态共享
Jun 03 #Javascript
深入理解JS异步编程-Promise
Jun 03 #Javascript
模块化react-router配置方法详解
Jun 03 #Javascript
react 组件传值的三种方法
Jun 03 #Javascript
angular使用md5,CryptoJS des加密的方法
Jun 03 #Javascript
Node.js 的 GC 机制详解
Jun 03 #Javascript
微信小程序蓝牙连接小票打印机实例代码详解
Jun 03 #Javascript
You might like
PHP 处理TXT文件(打开/关闭/检查/读取)
2013/05/13 PHP
CodeIgniter生成网站sitemap地图的方法
2013/11/13 PHP
thinkphp验证码显示不出来的解决方法
2014/03/29 PHP
PHP实现抓取HTTPS内容
2014/12/01 PHP
php中heredoc与nowdoc介绍
2014/12/25 PHP
PHP可变变量学习小结
2015/11/29 PHP
Laravel 5.5 的自定义验证对象/类示例代码详解
2017/08/29 PHP
Laravel框架路由和控制器的绑定操作方法
2018/06/12 PHP
javascript 自动填写表单的实现方法
2010/04/09 Javascript
让新消息在网页标题闪烁提示的jQuery代码
2013/11/04 Javascript
javascript实现点击商品列表checkbox实时统计金额的方法
2015/05/15 Javascript
jQuery实现鼠标跟随提示层效果代码(可显示文本,Div,Table,Html等)
2016/04/18 Javascript
JQuery validate插件Remote用法大全
2016/05/15 Javascript
JavaScript简单获取系统当前时间完整示例
2016/08/02 Javascript
vue+element-ui+axios实现图片上传
2019/08/20 Javascript
[02:32]“虐狗”镜头慎点 2016国际邀请赛中国区预选赛现场玩家采访
2016/06/28 DOTA
python中set常用操作汇总
2016/06/30 Python
对python中Matplotlib的坐标轴的坐标区间的设定实例讲解
2018/05/25 Python
详解如何在Apache中运行Python WSGI应用
2019/01/02 Python
Django 导出项目依赖库到 requirements.txt过程解析
2019/08/23 Python
selenium+python实现自动登陆QQ邮箱并发送邮件功能
2019/12/13 Python
python argparse传入布尔参数false不生效的解决
2020/04/20 Python
将python字符串转化成长表达式的函数eval实例
2020/05/11 Python
python 使用elasticsearch 实现翻页的三种方式
2020/07/31 Python
Python高并发和多线程有什么关系
2020/11/14 Python
python lambda的使用详解
2021/02/26 Python
新秀丽拉杆箱美国官方网站:Samsonite美国
2016/07/25 全球购物
味多美官网:蛋糕订购,100%使用天然奶油
2017/11/10 全球购物
本科生学习总结的自我评价
2013/10/02 职场文书
设计专业毕业生求职信
2014/06/25 职场文书
幼儿园教师的自我评价范文
2014/09/17 职场文书
大学新生军训自我鉴定
2014/09/18 职场文书
公司优秀员工推荐信
2015/03/24 职场文书
中国古风插画师排行榜:夏达第一,第三是阴阳师姑获鸟皮肤创作者
2022/03/18 国漫
《吸血鬼幸存者》新内容发布 追加多个全新模式
2022/04/07 其他游戏
搭建zabbix监控以及邮件报警的超级详细教学
2022/07/15 Servers