详解基于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 相关文章推荐
遨游,飞飞,IE,空中网 浏览器无提示关闭方法
Jul 11 Javascript
JS实现的网页倒计时数字时钟效果
Mar 02 Javascript
JS实现仿google、百度搜索框输入信息智能提示的实现方法
Apr 20 Javascript
JQuery中Bind()事件用法分析
May 05 Javascript
JS实现双击编辑可修改状态的方法
Aug 14 Javascript
跟我学习javascript创建对象(类)的8种方法
Nov 20 Javascript
JavaScript计划任务后台运行的方法
Dec 18 Javascript
关于javascript原型的修改与重写(覆盖)差别详解
Aug 31 Javascript
vue动态绑定组件子父组件多表单验证功能的实现代码
May 14 Javascript
Angular5中状态管理的实现
Sep 03 Javascript
使用javascript做时间倒数读秒功能的实例
Jan 23 Javascript
深入理解Vue keep-alive及实践总结
Aug 21 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
phpcms模块开发之swfupload的使用介绍
2013/04/28 PHP
基于PHP中的常用函数回顾
2013/07/11 PHP
详解PHP中foreach的用法和实例
2016/10/25 PHP
php设计模式之状态模式实例分析【星际争霸游戏案例】
2020/03/26 PHP
JavaScript高级程序设计(第3版)学习笔记5 js语句
2012/10/11 Javascript
javascript右下角弹层及自动隐藏(自己编写)
2013/11/20 Javascript
含有CKEditor的表单如何提交
2014/01/09 Javascript
toggle()隐藏问题的解决方法
2014/02/17 Javascript
自写的jQuery异步加载数据添加事件
2014/05/15 Javascript
node.js中的fs.futimesSync方法使用说明
2014/12/17 Javascript
使用jQuery仿苹果官网焦点图特效
2014/12/23 Javascript
基于SpringMVC+Bootstrap+DataTables实现表格服务端分页、模糊查询
2016/10/30 Javascript
Bootstrap框架实现广告轮播效果
2016/11/28 Javascript
详解webpack提取第三方库的正确姿势
2017/12/22 Javascript
layui 优化button按钮和弹出框的方法
2018/08/15 Javascript
JS Ajax请求会话过期处理问题解决方法分析
2019/11/16 Javascript
使用Python判断IP地址合法性的方法实例
2014/03/13 Python
matplotlib 纵坐标轴显示数据值的实例
2018/05/25 Python
Python3.7 读取音频根据文件名生成脚本的代码
2020/04/07 Python
基于python实现数组格式参数加密计算
2020/04/21 Python
葡萄牙鞋子品牌:Fair
2016/12/10 全球购物
电子商务专业学生的自我鉴定
2013/11/28 职场文书
自我鉴定怎么写
2013/12/05 职场文书
写给爸爸的道歉信
2014/01/15 职场文书
入党自我评价范文
2014/02/02 职场文书
仓库主管岗位职责
2014/03/02 职场文书
作风大整顿心得体会
2014/09/10 职场文书
教师四风自我剖析材料
2014/09/30 职场文书
2015年见习期工作总结
2014/12/12 职场文书
高中生思想道德自我评价
2015/03/09 职场文书
幼儿园教师求职信
2015/03/20 职场文书
复兴之路观后感3000字
2015/06/02 职场文书
2015年度学校应急管理工作总结
2015/10/22 职场文书
python 如何用map()函数创建多线程任务
2021/04/07 Python
Hive HQL支持2种查询语句风格
2022/06/25 数据库