详解基于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 相关文章推荐
一种JavaScript的设计模式
Nov 22 Javascript
Javascript 个人笔记(没有整理,很乱)
Jul 07 Javascript
Javascript valueOf 使用方法
Dec 28 Javascript
jQuery 幻灯片插件(带缩略图功能)
Jan 24 Javascript
JS事件Event元素(兼容IE,Firefox,Chorme)
Nov 01 Javascript
js中window.open()的所有参数详细解析
Jan 09 Javascript
javascript的alert box在java中如何显示多行
May 18 Javascript
js图片跟随鼠标移动代码
Nov 26 Javascript
微信小程序 富文本转文本实例详解
Oct 24 Javascript
jQuery实现带右侧索引功能的通讯录示例【附源码下载】
Apr 17 jQuery
vue-cli脚手架build目录下utils.js工具配置文件详解
Sep 14 Javascript
vue.js中使用微信扫一扫解决invalid signature问题(完美解决)
Apr 11 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 ADODB使用方法集锦
2008/03/25 PHP
php导出word格式数据的代码实例
2013/11/25 PHP
PHP学习笔记之session
2018/05/06 PHP
php成功操作redis cluster集群的实例教程
2019/01/13 PHP
自动完成JS类(纯JS, Ajax模式)
2009/03/12 Javascript
DWR Ext 加载数据
2009/03/22 Javascript
基于jQuery的Spin Button自定义文本框数值自增或自减
2010/07/17 Javascript
使用Jquery打造最佳用户体验的登录页面的实现代码
2011/07/08 Javascript
JS的document.all函数使用示例
2013/12/30 Javascript
jQuery+JSON实现AJAX二级联动实例分析
2015/12/18 Javascript
Bootstarp 基础教程之表单部分实例代码
2017/02/03 Javascript
javascript ES6中箭头函数注意细节小结
2017/02/17 Javascript
js实现网页定位导航功能
2017/03/07 Javascript
Node.js自定义实现文件路由功能
2017/09/22 Javascript
angular学习之动态创建表单的方法
2018/12/07 Javascript
JavaScript实现图片的放大缩小及拖拽功能示例
2019/05/14 Javascript
Vue中跨域及打包部署到nginx跨域设置方法
2019/08/26 Javascript
深入浅析golang zap 日志库使用(含文件切割、分级别存储和全局使用等)
2020/02/19 Javascript
使用vue构建多页面应用的示例
2020/10/22 Javascript
[01:16:50]DOTA2-DPC中国联赛 正赛 Phoenix vs CDEC BO3 第一场 3月7日
2021/03/11 DOTA
python解析发往本机的数据包示例 (解析数据包)
2014/01/16 Python
python列表操作使用示例分享
2014/02/21 Python
Django1.9 加载通过ImageField上传的图片方法
2018/05/25 Python
CentOS 7下安装Python3.6 及遇到的问题小结
2018/11/08 Python
python实现彩色图转换成灰度图
2019/01/15 Python
浅谈python元素如何去重,去重后如何保持原来元素的顺序不变
2020/02/28 Python
Jmeter HTTPS接口测试证书导入过程图解
2020/07/22 Python
Europcar德国:全球汽车租赁领域的领导者
2018/08/15 全球购物
全球领先的中国制造商品在线批发平台:DHgate
2020/01/28 全球购物
策划主管的工作职责
2013/11/24 职场文书
动漫专业高职生职业生涯规划书
2014/02/15 职场文书
党课培训主持词
2014/04/01 职场文书
难忘的一课教学反思
2014/04/30 职场文书
反腐倡廉观后感
2015/06/08 职场文书
公安干警正风肃纪心得体会
2016/01/15 职场文书
用Python爬取各大高校并可视化帮弟弟选大学,弟弟直呼牛X
2021/06/11 Python