详解基于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 相关文章推荐
js阻止冒泡及jquery阻止事件冒泡示例介绍
Nov 19 Javascript
javascript中的事件代理初探
Mar 08 Javascript
jQuery的Read()方法代替原生JS详解
Nov 08 Javascript
基于js实现checkbox批量选中操作
Nov 22 Javascript
Vue.js自定义指令的用法与实例解析
Jan 18 Javascript
jQuery树控件zTree使用方法详解(一)
Feb 28 Javascript
jquery.guide.js新版上线操作向导镂空提示jQuery插件(推荐)
May 20 jQuery
layer.confirm取消按钮绑定事件的方法
Aug 17 Javascript
js实现文件上传功能 后台使用MultipartFile
Sep 08 Javascript
详解es6新增数组方法简便了哪些操作
May 09 Javascript
微信小程序 WXML节点信息查询详解
Jul 29 Javascript
vue使用watch监听属性变化
Apr 30 Vue.js
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
收听困难?教您超简便短波广播抗干扰方法!
2021/03/01 无线电
PHP长连接实现与使用方法详解
2018/02/11 PHP
php正则表达式使用方法整理集合
2020/01/31 PHP
location.href 在IE6中不跳转的解决方法与推荐使用代码
2010/07/08 Javascript
读jQuery之九 一些瑕疵说明
2011/06/21 Javascript
javascript椭圆旋转相册实现代码
2012/01/16 Javascript
jQuery之$(document).ready()使用介绍
2012/04/05 Javascript
jquery实现不同大小浏览器使用不同的css样式表的方法
2014/04/02 Javascript
JavaScript获取页面中第一个锚定文本的方法
2015/04/03 Javascript
细数JavaScript 一个等号,两个等号,三个等号的区别
2016/10/09 Javascript
分类解析jQuery选择器
2016/11/23 Javascript
Angularjs根据json文件动态生成路由状态的实现方法
2017/04/17 Javascript
vue自定义filters过滤器
2018/04/26 Javascript
jQuery实现table表格checkbox全选的方法分析
2018/07/04 jQuery
vue1.0和vue2.0的watch监听事件写法详解
2018/09/11 Javascript
js中的闭包实例展示
2018/11/01 Javascript
JavaScript Date对象功能与用法学习记录
2020/04/28 Javascript
js对象属性名驼峰式转下划线的实例代码
2020/09/17 Javascript
JS实现购物车基本功能
2020/11/08 Javascript
比较详细Python正则表达式操作指南(re使用)
2008/09/06 Python
Python入门篇之文件
2014/10/20 Python
python中for用来遍历range函数的方法
2018/06/08 Python
元组列表字典(莫烦python基础)
2019/04/03 Python
Python静态类型检查新工具之pyright 使用指南
2019/04/26 Python
python 同时读取多个文件的例子
2019/07/16 Python
对Python3中列表乘以某一个数的示例详解
2019/07/20 Python
详解如何在PyCharm控制台中输出彩色文字和背景
2020/08/17 Python
Space NK英国站:英国热门美妆网站
2017/12/11 全球购物
英国亚马逊官方网站:Amazon.co.uk
2019/08/09 全球购物
环境工程与管理大学毕业生求职信
2013/10/02 职场文书
会计主管岗位职责范文
2013/11/08 职场文书
如何打造一封优秀的留学推荐信
2014/01/25 职场文书
公司经理任命书
2014/06/05 职场文书
给老师的感谢信
2015/01/20 职场文书
基于Nginx实现限制某IP短时间访问次数
2021/03/31 Servers
详细聊聊MySQL中慢SQL优化的方向
2021/08/30 MySQL