详解基于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 相关文章推荐
jQuery EasyUI 的EasyLoader功能介绍
Sep 12 Javascript
js弹出模式对话框,并接收回传值的方法
Mar 12 Javascript
jquery根据name属性查找的小例子
Nov 21 Javascript
javascript的alert box在java中如何显示多行
May 18 Javascript
node.js中的path.isAbsolute方法使用说明
Dec 08 Javascript
深入理解JS函数的参数(arguments)的使用
May 28 Javascript
jQuery实现单击按钮遮罩弹出对话框效果(2)
Feb 20 Javascript
浅谈node中的cluster集群
Jun 02 Javascript
react native 获取地理位置的方法示例
Aug 28 Javascript
js实现点击图片在屏幕中间弹出放大效果
Sep 11 Javascript
js使用文档就绪函数动态改变页面内容示例【innerHTML、innerText】
Nov 07 Javascript
Vue实现简单的留言板
Oct 23 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
非常不错的MySQL优化的8条经验
2008/03/24 PHP
ThinkPHP令牌验证实例
2014/06/18 PHP
使用WordPress发送电子邮件的相关PHP函数用法解析
2015/12/15 PHP
PHP设置头信息及取得返回头信息的方法
2016/01/25 PHP
PHP如何获取Cookie并实现模拟登录
2020/07/16 PHP
javascript中运用闭包和自执行函数解决大量的全局变量问题
2010/12/30 Javascript
js 一个关于图片onload加载的事
2013/11/10 Javascript
js鼠标及对象坐标控制属性详细解析
2013/12/14 Javascript
Node.js实现Excel转JSON
2015/04/24 Javascript
深入理解js数组的sort排序
2016/05/28 Javascript
Node.js使用Express创建Web项目详细教程
2017/03/31 Javascript
Vue.js 2.0学习教程之从基础到组件详解
2017/04/24 Javascript
jquery实现tab选项卡切换效果(悬停、下方横线动画位移)
2017/05/05 jQuery
Vue.js构建你的第一个包并在NPM上发布的方法步骤
2019/05/01 Javascript
小程序采集录音并上传到后台
2019/11/22 Javascript
零基础写python爬虫之抓取百度贴吧代码分享
2014/11/06 Python
Django的session中对于用户验证的支持
2015/07/23 Python
基于Python如何使用AIML搭建聊天机器人
2016/01/27 Python
python中正则的使用指南
2016/12/04 Python
PyQt5每天必学之像素图控件QPixmap
2018/04/19 Python
Python2.7.10以上pip更新及其他包的安装教程
2018/06/12 Python
Django后台管理系统的图文使用教学
2020/01/20 Python
python 中不同包 类 方法 之间的调用详解
2020/03/09 Python
python使用pymongo与MongoDB基本交互操作示例
2020/04/09 Python
Python+Dlib+Opencv实现人脸采集并表情判别功能的代码
2020/07/01 Python
Python jieba库分词模式实例用法
2021/01/13 Python
中学生爱国演讲稿
2013/12/31 职场文书
优秀少先队大队辅导员事迹材料
2014/05/04 职场文书
没有孩子的离婚协议书怎么写
2014/09/17 职场文书
2014年学校财务工作总结
2014/12/06 职场文书
2015年个人思想总结
2015/03/09 职场文书
2015年底工作总结范文
2015/05/15 职场文书
离婚财产分割协议书
2015/08/11 职场文书
分位数回归模型quantile regeression应用详解及示例教程
2021/11/02 Python
css常用字体属性与背景属性介绍
2022/02/28 HTML / CSS
动作冒险《Hell Is Us》将采用虚幻5 消灭怪物探索王国
2022/04/13 其他游戏