详解基于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的初始化与对象构建之浅析
Apr 12 Javascript
动态的改变IFrame的高度实现IFrame自动伸展适应高度
Dec 28 Javascript
浅析javascript的间隔调用和延时调用
Nov 12 Javascript
jQuery实现ToolTip元素定位显示功能示例
Nov 23 Javascript
node.js 核心http模块,起一个服务器,返回一个页面的实例
Sep 11 Javascript
vue实现商城上货组件简易版
Nov 27 Javascript
Parcel 打包示例(React HelloWorld)
Jan 16 Javascript
关于vue中 $emit的用法详解
Apr 12 Javascript
JS简单生成由字母数字组合随机字符串示例
May 25 Javascript
vue实现弹幕功能
Oct 25 Javascript
vue组件创建的三种方式小结
Feb 03 Javascript
Vue如何跨组件传递Slot的实现
Dec 14 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
配置最新的PHP加MYSQL服务器
2006/10/09 PHP
php 在线导入mysql大数据程序
2015/06/11 PHP
使用PHP实现微信摇一摇周边红包
2016/01/04 PHP
Smarty保留变量用法分析
2016/05/23 PHP
php使用flock阻塞写入文件和非阻塞写入文件的实例讲解
2017/07/10 PHP
CentOS7系统搭建LAMP及更新PHP版本操作详解
2020/03/26 PHP
javascript 面向对象全新理练之继承与多态
2009/12/03 Javascript
JavaScript日历实现代码
2010/09/12 Javascript
使用命令对象代替switch语句的写法示例
2015/02/28 Javascript
js实现选中复选框文字变色的方法
2015/08/14 Javascript
js格式化时间的方法
2015/12/18 Javascript
JS前向后瞻正则表达式定义与用法示例
2016/12/27 Javascript
vue图片加载与显示默认图片实例代码
2017/03/16 Javascript
ES6新特性之模块Module用法详解
2017/04/01 Javascript
VueJs单页应用实现微信网页授权及微信分享功能示例
2017/07/26 Javascript
开发Vue树形组件的示例代码
2017/12/21 Javascript
微信小程序实现两边小中间大的轮播效果的示例代码
2018/12/07 Javascript
详解jQuery-each()方法
2019/03/13 jQuery
js实现双色球效果
2020/08/02 Javascript
JavaScript实现雪花飘落效果
2020/12/27 Javascript
Python实现Logger打印功能的方法详解
2017/09/01 Python
Zookeeper接口kazoo实例解析
2018/01/22 Python
python实现手机销售管理系统
2019/03/19 Python
基于python获取本地时间并转换时间戳和日期格式
2020/10/27 Python
Python爬虫UA伪装爬取的实例讲解
2021/02/19 Python
html5 application cache遇到的严重问题
2012/12/26 HTML / CSS
Alba Moda德国网上商店:意大利时尚女装销售
2016/11/14 全球购物
台湾母婴用品购物网站:Infant婴之房
2018/06/15 全球购物
物流仓储实习自我鉴定
2013/09/25 职场文书
校三好学生主要事迹
2014/01/11 职场文书
党员干部承诺书范文
2014/03/25 职场文书
党建工作先进材料
2014/05/02 职场文书
社区平安建设方案
2014/05/25 职场文书
2014年党小组工作总结
2014/12/20 职场文书
《天净沙·秋思》教学反思三篇
2019/11/02 职场文书
python基础之错误和异常处理
2021/10/24 Python