详解基于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 onload处理html页面加载之后的事件
Oct 30 Javascript
js继承call()和apply()方法总结
Dec 08 Javascript
JS弹出对话框实现方法(三种方式)
Dec 18 Javascript
点击页面任何位置隐藏div的实现方法
Sep 05 Javascript
React Native实现简单的登录功能(推荐)
Sep 19 Javascript
JS优化与惰性载入函数实例分析
Apr 06 Javascript
p5.js入门教程之小球动画示例代码
Mar 15 Javascript
微信小程序云开发之使用云函数
May 17 Javascript
JavaScript冒泡算法原理与实现方法深入理解
Jun 04 Javascript
Vue父子之间值传递的实例教程
Jul 02 Javascript
详解vue3.0 的 Composition API 的一种使用方法
Oct 26 Javascript
JavaScript实现表单验证功能
Dec 09 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
体育彩票排列三组选三算法分享
2014/03/07 PHP
php通过获取头信息判断图片类型的方法
2015/06/26 PHP
浅谈laravel中的关联查询with的问题
2019/10/10 PHP
php适配器模式简单应用示例
2019/10/23 PHP
JavaScript Event学习第九章 鼠标事件
2010/02/08 Javascript
基于jquery的网页SELECT下拉框美化代码
2010/10/28 Javascript
EasyUI中的tree用法介绍
2011/11/01 Javascript
jquery indexOf使用方法
2013/08/19 Javascript
JS和Jquery获取和修改label的值的示例代码
2014/01/15 Javascript
JavaScript参数个数可变的函数举例说明
2014/10/10 Javascript
Bootstrap基础学习
2015/06/16 Javascript
jquery实现表单验证并阻止非法提交
2015/07/09 Javascript
jquery-tips悬浮提示插件分享
2015/07/31 Javascript
基于jquery实现最简单的选项卡切换效果
2016/05/08 Javascript
js实现div模拟模态对话框展现URL内容
2016/05/27 Javascript
JS匿名函数实例分析
2016/11/26 Javascript
JavaScript数组去重的6个方法
2017/01/21 Javascript
H5手机端多文件上传预览插件
2017/04/21 Javascript
BootStrap daterangepicker 双日历控件
2017/06/02 Javascript
JavaScript 几种循环方式以及模块化的总结
2020/09/03 Javascript
js实现3D粒子酷炫动态旋转特效
2020/09/13 Javascript
[02:14]DOTA2英雄基础教程 修补匠
2013/12/23 DOTA
Python中的日期时间处理详解
2016/11/17 Python
Python信息抽取之乱码解决办法
2017/06/29 Python
详解python上传文件和字符到PHP服务器
2017/11/24 Python
python 用正则表达式筛选文本信息的实例
2018/06/05 Python
Django框架model模型对象验证实现方法分析
2019/10/02 Python
Python实现AI换脸功能
2020/04/10 Python
pyecharts在数据可视化中的应用详解
2020/06/08 Python
解决Keras中循环使用K.ctc_decode内存不释放的问题
2020/06/29 Python
英国优质家居用品网上品牌:URBANARA
2018/06/01 全球购物
Arti-shopping中文官网:大型海外商品一站式直邮平台
2020/03/23 全球购物
企业道德讲堂实施方案
2014/03/19 职场文书
股东授权委托书范文
2014/09/13 职场文书
天河观后感
2015/06/11 职场文书
教你怎么用Python生成九宫格照片
2021/05/20 Python