详解基于vue-router的动态权限控制实现方案


Posted in Javascript onSeptember 28, 2017

使用vue开发带权限管理系统,尤其是采用了vue-router做路由,很多人都遇到的一个问题就是如何动态加载路由path对应的component。

典型的应用场景就是:前端菜单不静态的写在vue程序里,而是要从后台程序和数据库返回的菜单来动态加载到vue应用中。

网上很多问权限的问题,但几乎找不到很好的解决答案,在很长一段时间里,非常打击使用vue技术栈开发的信心。最有质量的一篇文章是:https://3water.com/article/124801.htm

但作者并没有完全解决这个问题,还留有几个问题是:

1)登录之后跳转到首页,此时路由已经是加载完成的了不能更改,菜单可以显示但是没有路由。

2)前端应用人为刷新网页路由产生某些问题。

本文即在这篇文章的基础上对这两个问题解决,以使其完整。

前提是认真拜读上面提到的那篇文章,下面直接用代码说话:

问题1的解决思路:

登录之后跳转到首页,router是vue应用的router 引入进登录方法,在登录之后跳转之前对router进行改变,改变要点1是精确赋值到router的routes具体地方,比如我这里是routes[0]的子路由,2是用addRoutes函数使其生效。

登录功能的js

export const login = ({commit}, data) => { Service.post('/login', Qs.stringify(data))
  .then(res => {
   const success = Object.is(res.statusText, 'OK') && Object.is(res.data.code, '0')
   if (success) {
    var menus = generateMenus(res.data.menus)
    window.sessionStorage.routes = JSON.stringify(menus)
    if (menuModule.state.items.length <= 0) { // 避免注销后在不刷新页面的情况下再登录重复加载路由
     commit(types.ADD_MENU, menus)
     // 动态加载路由关键2行
     router.options.routes[0].children.push(...generateRoutesFromMenu(menuModule.state.items))
     router.addRoutes(router.options.routes)
    }
    window.sessionStorage.loginName = data.loginName
    router.push({path: '/'})
   } else {
    commit('loginErr', res.data.msg)
   }
  })
}


function generateRoutesFromMenu (menu = [], routes = []) {
 for (let i = 0, l = menu.length; i < l; i++) {
  let item = menu[i]
  if (item.path) {
   routes.push(item)
  }
  if (!item.component) {
   item.component = resolve => require([`views/` + item.component + `.vue`], resolve)
   generateRoutesFromMenu(item.children, routes)
  }
 }
 return routes
}

问题2的解决思路:

是不在主app里引入实例化vue-router的js,而是直接在app里实例化router,目的就是网页刷新的时候每次都确保生成动态的router。

app.js部分代码:

Vue.use(Router)
let menus = window.sessionStorage.routes //登录成功返回的菜单
if (menus) {
 let items = JSON.parse(menus)
 store.commit(ADD_MENU, items)
}

const router = new Router({
 mode: 'hash',
 linkActiveClass: 'is-active',
 scrollBehavior: () => ({ y: 0 }),
 routes: [
  {
   name: 'Main',
   path: '/',
   component: require('views/Main.vue'),
   children: [ //动态路由之所以作为Main的子路由是基于:登录之后跳转到Main主页,该主页是类似于frame的页面加载框架,只有将动态路由作为Main的子路由才能确保其他页面显示到Main框架内。
    ...generateRoutesFromMenu(menuModule.state.items)
   ]
  },
  {
   name: 'Login',
   path: '/login',
   component: require('views/Login.vue')
  }
 ]
})

function generateRoutesFromMenu (menu = [], routes = []) {
 for (let i = 0, l = menu.length; i < l; i++) {
  let item = menu[i]
  if (item.path) {
   routes.push(item)
  }
  if (!item.component) {
   item.component = resolve => require([`views/` + item.component + `.vue`], resolve)
   generateRoutesFromMenu(item.children, routes)
  }
 }
 return routes
}

另附menu items代码

const state = {
 items: [ // 什么菜单都不定义,完全由后端返回
 ]
}
const mutations = {
 [types.ADD_MENU] (state, menuItems) {
  if (menuItems.length > 0) {
   menuItems.map(function (item) {
    item.children.map(function (child) {
     child.component = lazyLoading(child.component)
    })
   })
   state.items.push(...menuItems)
  }
 },

lazyloding

export default (name, index = false) => () => import(`views/${name}${index ? '/index' : ''}.vue`)

git代码暂不能全部公开,有问题可留言。

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

Javascript 相关文章推荐
HTML-CSS群中单选引发的“事件”
Mar 05 Javascript
阻止JavaScript事件冒泡传递(cancelBubble 、stopPropagation)
May 08 Javascript
测试JavaScript字符串处理性能的代码
Dec 07 Javascript
jquery dialog键盘事件代码
Aug 01 Javascript
如何将一个String和多个String值进行比较思路分析
Apr 22 Javascript
利用原生js和jQuery实现单选框的勾选和取消操作的方法
Sep 04 Javascript
JavaScript登录记住密码操作(超简单代码)
Mar 22 Javascript
Vuex简单入门
Apr 19 Javascript
node中间层实现文件上传功能
Jun 11 Javascript
js嵌套的数组扁平化:将多维数组变成一维数组以及push()与concat()区别的讲解
Jan 19 Javascript
小程序跳转H5页面的方法步骤
Mar 06 Javascript
解决iView Table组件宽度只变大不变小的问题
Nov 13 Javascript
node.js学习之断言assert的使用示例
Sep 28 #Javascript
vue-router+vuex addRoutes实现路由动态加载及菜单动态加载
Sep 28 #Javascript
node.js学习之事件模块Events的使用示例
Sep 28 #Javascript
es6中的解构赋值、扩展运算符和rest参数使用详解
Sep 28 #Javascript
JS获取日期的方法实例【昨天,今天,明天,前n天,后n天的日期】
Sep 28 #Javascript
jquery实现左右轮播图效果
Sep 28 #jQuery
bootstrap table实现点击翻页功能 可记录上下页选中的行
Sep 28 #Javascript
You might like
十天学会php之第二天
2006/10/09 PHP
php REMOTE_ADDR之获取访客IP的代码
2008/04/22 PHP
Linux下从零开始安装配置Nginx服务器+PHP开发环境
2015/12/21 PHP
PHP生成(支持多模板)二维码海报代码
2018/04/30 PHP
PHPExcel实现表格导出功能示例【带有多个工作sheet】
2018/06/13 PHP
javascript中window.event事件用法详解
2012/12/11 Javascript
JQuery boxy插件在IE中边角图片不显示问题的解决
2015/05/20 Javascript
javascript作用域链(Scope Chain)用法实例解析
2015/11/30 Javascript
AngularJs 国际化(I18n/L10n)详解
2016/09/01 Javascript
详解angular element()方法使用
2017/04/08 Javascript
JS HTML图片显示Canvas 压缩功能
2017/07/21 Javascript
VueJS 取得 URL 参数值的方法
2019/07/19 Javascript
layui监听工具栏的实例(操作列表按钮)
2019/09/10 Javascript
解决layui的table插件无法多层级获取json数据的问题
2019/09/19 Javascript
js中switch语句的学习笔记
2020/03/25 Javascript
[03:24]2014DOTA2国际邀请赛 神秘商店生意火爆
2014/07/18 DOTA
Python不规范的日期字符串处理类
2014/06/10 Python
用Python实现web端用户登录和注册功能的教程
2015/04/30 Python
Python解析最简单的验证码
2016/01/07 Python
python爬虫_微信公众号推送信息爬取的实例
2017/10/23 Python
Python生成器的使用方法和示例代码
2019/03/04 Python
python pycharm最新版本激活码(永久有效)附python安装教程
2020/09/18 Python
python使用梯度下降算法实现一个多线性回归
2020/03/24 Python
使用Python+Appuim 清理微信的方法
2021/01/26 Python
利用HTML5+css3+jquery+weui实现仿微信聊天界面功能
2018/01/08 HTML / CSS
Farnell德国:电子元器件供应商
2018/07/10 全球购物
软件测试题目
2013/02/27 面试题
专营店会计助理岗位职责
2013/11/29 职场文书
毕业生如何写自荐信
2014/03/26 职场文书
电脑售后服务承诺书
2014/03/27 职场文书
经济类毕业生求职信
2014/06/26 职场文书
后勤管理员岗位职责
2014/08/27 职场文书
大学生党性分析材料
2014/12/19 职场文书
少先队辅导员事迹材料
2014/12/24 职场文书
英语导游欢迎词
2015/09/30 职场文书
详解Spring Boot使用系统参数表提升系统的灵活性
2021/06/30 Java/Android