详解基于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 iframe编程相关代码
Dec 28 Javascript
javascript游戏开发之《三国志曹操传》零部件开发(五)可移动地图的实现
Jan 23 Javascript
自动刷新网页,自动刷新当前页面,JS调用
Jun 24 Javascript
3种Jquery限制文本框只能输入数字字母的方法
Dec 03 Javascript
js使用DOM操作实现简单留言板的方法
Apr 10 Javascript
在JavaScript的正则表达式中使用exec()方法
Jun 16 Javascript
bootstrap flask登录页面编写实例
Nov 01 Javascript
详解Angular2表单-模板驱动的表单(Template-Driven Forms)
Aug 04 Javascript
在 Angular6 中使用 HTTP 请求服务端数据的步骤详解
Aug 06 Javascript
vue2中使用sass并配置全局的sass样式变量的方法
Sep 04 Javascript
详解解决Vue相同路由参数不同不会刷新的问题
Oct 12 Javascript
JavaScript中.min.js和.js文件的区别讲解
Feb 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中ob(Output Buffer 输出缓冲)函数使用方法
2007/07/21 PHP
如何在PHP程序中防止盗链
2008/04/09 PHP
smarty模板引擎之分配数据类型
2015/03/30 PHP
php实现数组中索引关联数据转换成json对象的方法
2015/07/08 PHP
php高清晰度无损图片压缩功能的实现代码
2018/12/09 PHP
php实现文件上传基本验证
2020/03/04 PHP
设置iframe的document.designMode后仅Firefox中其body.innerHTML为br
2012/02/27 Javascript
javascript使用for循环批量注册的事件不能正确获取索引值的解决方法
2014/12/20 Javascript
jQuery基础_入门必看知识点
2016/07/04 Javascript
浅析如何利用JavaScript进行语音识别
2016/10/27 Javascript
原生js实现商品放大镜效果
2017/01/12 Javascript
使用Bootstrap美化按钮实例代码(demo)
2017/02/03 Javascript
详解axios在node.js中的post使用
2017/04/27 Javascript
基于Vue实现拖拽效果
2018/04/27 Javascript
解决vue2.0 element-ui中el-upload的before-upload方法返回false时submit()不生效问题
2018/08/24 Javascript
Python计算程序运行时间的方法
2014/12/13 Python
学习python 之编写简单乘法运算题
2016/02/27 Python
解析Python中的生成器及其与迭代器的差异
2016/06/20 Python
利用Python开发实现简单的记事本
2016/11/15 Python
浅谈利用numpy对矩阵进行归一化处理的方法
2018/07/11 Python
python使用正则筛选信用卡
2019/01/27 Python
详解numpy.meshgrid()方法使用
2019/08/01 Python
Python pip安装第三方库实现过程解析
2020/07/09 Python
Django框架实现在线考试系统的示例代码
2020/11/30 Python
详解CSS3原生支持div铺满浏览器的方法
2018/08/30 HTML / CSS
新英格兰最大的特色礼品连锁店:The Paper Store
2018/07/23 全球购物
美丽的现代设计家具:2Modern
2018/07/26 全球购物
.NET面试题:什么是反射
2016/09/30 面试题
函授本科自我鉴定
2014/02/04 职场文书
2014年学前班工作总结
2014/12/08 职场文书
2014个人年度工作总结
2014/12/15 职场文书
2019奶茶店创业计划书范本!
2019/07/15 职场文书
如何利用map实现Nginx允许多个域名跨域
2021/03/31 Servers
Redis遍历所有key的两个命令(KEYS 和 SCAN)
2021/04/12 Redis
端午节将至,用Python爬取粽子数据并可视化,看看网友喜欢哪种粽子吧!
2021/06/11 Python
SpringBoot集成Druid连接池连接MySQL8.0.11
2021/07/02 Java/Android