vue+elementui搭建后台管理界面(6登录和菜单权限控制[二])
根据权限计算路由的代码
/**
* 通过meta.role判断是否与当前用户权限匹配
* @param roles
* @param route
*/
function hasRoles (roles, route) {
if (route.meta && route.meta.roles) {
return roles.some(role => route.meta.roles.includes(role))
} else {
return false
}
}
/**
* 递归过滤异步路由表,返回符合用户角色权限的路由表
* @param routes asyncRouterMap
* @param roles
*/
function filterAsyncRouter(asyncRouterMap, roles) {
const accessedRouters = asyncRouterMap.filter(route => {
// 404
if(route.path === '*'){
return true
}else if (hasRoles(roles, route)) {
if (route.children && route.children.length) {
route.children = filterAsyncRouter(route.children, roles)
}
return true
}
return false
})
return accessedRouters
}
GenerateRoutes ({ commit }, data) {
return new Promise(resolve => {
const { roles } = data
let accessedRouters
if (roles.includes('admin')) {
accessedRouters = asyncRouterMap
} else {
accessedRouters = filterAsyncRouter(asyncRouterMap, roles)
}
commit('SET_ROUTERS', accessedRouters)
resolve()
})
},
以上函数接收异步路由表、权限列表,返回在权限列表中的路由,保存在 state.addRouters 中
动态显示顶部导航和侧边栏
根据 state.addRouters 中的路由,动态生成顶部导航和侧边栏菜单
// 在有权限的路由表里,查找是否有到目标path的路由
// 为了保持路由唯一性,拼接父子路由
function hasDestRoute (froute, permitRouterMap, to) {
let r = froute === '/' ? '' : froute
return permitRouterMap.some(route => {
let path = r + '/' + route.path
if (to.path.indexOf(path) !== -1) {
return true;
}
if (route.children && route.children.length) { //如果有孩子就遍历孩子
return hasDestRoute(path, route.children, to)
}
})
}
/** ...省略的代码 */
SET_NOW_ROUTERS: (state, to) => {
// 由于首页重定向到 /dashboard,并且不参与权限控制,特殊处理
if(to.path === '/dashboard'){
let dashboard = state.routers.filter(v => v.path === '/' )
state.sidebar_routers = dashboard[0]
}else{
// 递归访问 accessedRouters,找到包含to 的那个路由对象,设置给 sidebar_routers
state.addRouters.forEach(e => {
if (e.children && e.children.length) {
if ( hasDestRoute2(e.path, e.children, to)){
if(state.sidebar_routers.path){
// 存在 sidebar_routers 且与目标路由不同
if(state.sidebar_routers.path !== e.path){
state.sidebar_routers = e;
}
}else{
state.sidebar_routers = e;
}
}
}
})
}
}
关键的控制代码
在路由跳转前,判断是否登录、拉取权限、生成菜单等
function hasPermission(roles, permissionRoles) {
if (roles.indexOf('admin') >= 0) {
return true // admin权限 直接通过
}
// 没有配置权限的菜单直接进入
if (!permissionRoles){
return true
}
return roles.some(role => permissionRoles.indexOf(role) >= 0)
}
/** ...省略的代码 */
const whiteList = ['/login',] // 不重定向白名单
router.beforeEach((to, from, next) => {
// 切换路由时清空上个路由未完成的所有请求
const cancelToken = axios.CancelToken
clearRequest.source.cancel && clearRequest.source.cancel('CANCELD_BY_USER')
clearRequest.source = cancelToken.source()
// 在免登录白名单,直接进入
if(whiteList.indexOf(to.path) !== -1){
next()
}else{
if(store.getters.token) {
if (to.path === '/login') {
next({ path: '/' })
NProgress.done() //
}else{
// 判断当前用户是否已拉取完user_info信息
if(store.getters.roles.length === 0){
// 拉取用户信息
store.dispatch('GetUserInfo')
.then(resp => {
const roles = resp.data.roles
store.dispatch('GenerateRoutes', {roles})
.then(()=>{
// 根据roles权限生成可访问的路由表
// 动态添加可访问路由表
router.addRoutes(store.getters.addRouters)
next({...to, replace: true})
})
})
.catch((err) => {
store.dispatch('FedLogOut').then(()=>{
Message.error({
message: err || '认证失败,请重新登录',
duration: 2000,
})
next({ path: '/login' })
})
})
}else{
console.log('call GenSidebarRoutes')
store.dispatch('GenSidebarRoutes', to)
.then(()=> {
if(hasPermission(store.getters.roles, to.meta.role)){
next()
}else{
next({
path: '/',
query: {noGoBack: true}
})
}
})
}
}
}else{
// 重定向到登录页
next({
path: '/login',
query: {redirect: to.fullpath}
})
}
}
})
vue+elementui搭建后台管理界面(6登录和菜单权限控制[二])的更多相关文章
- vue+elementui搭建后台管理界面(6登录和菜单权限控制)
不同的权限对应不同的路由(菜单),同时侧边栏也根据权限异步生成,实现登录和鉴权思路如下: 登录:点击登录,服务器验证通过后返回一个 token ,然后存到 cookie,再根据 token 拉取用户权 ...
- vue+elementui搭建后台管理界面(1登录)
1 node环境安装 从 node官网下载安装包 2 vue-cli npm install vue-cli -g 3 新建项目 vue init webpack vue-project 可保持默认, ...
- vue+elementui搭建后台管理界面(7 vuex和mockjs的使用)
将权限管理应用到系统,首先做好登录, 点击登录按钮后,触发以下动作 vuex 中的 login 动作,设置 cookie vuex 中的 getuserinfo , 获取权限.用户名.头像等 由于目前 ...
- vue+elementui搭建后台管理界面(2首页)
1 会话存储 使用html5的 sessionStorage 对象临时保存会话 // 保存会话 sessionStorage.setItem('user', username) // 删除会话 ses ...
- vue+elementui搭建后台管理界面
1 会话存储 使用html5的 sessionStorage 对象临时保存会话 // 保存会话 sessionStorage.setItem('user', username) // 删除会话 ses ...
- vue+elementui搭建后台管理界面(8 同步/异步获取数据渲染table)
elementui已经封装好了 el-table 组件,只需要指定 data 数据源即可,因此通常在 vue 实例生命周期的 created 阶段,从数据库获取数据,再将返回的数据绑定到 data 如 ...
- vue+elementui搭建后台管理界面(5递归生成侧栏路由)
有一个菜单树,顶层菜单下面有多个子菜单,子菜单下还有子菜单... 这时候就要用递归处理 1 定义多级菜单 修改 src/router/index.js 的 / 路由 { path: '/', redi ...
- vue+elementui搭建后台管理界面(3侧边栏菜单)
上一节搭好了主框架,但是标签页和侧边栏只是分别展示了各自的菜单,如何将二者联动起来? 定义路由规则:当有 children 属性时,从 children 里取出 path 填充到侧边栏,如: { pa ...
- vue+elementui搭建后台管理界面(4使用font-awesome)
使用font-awesome npm install --save font-awesome 修改 src/main.js 增加 import 'font-awesome/scss/font-awes ...
随机推荐
- 英语foteball足球历史
foteball n.足球 现代足球 参见:现代足球 现代足球起源地是在英格兰.传说在11世纪,英格兰与丹麦之间有过一场战争,战争结束后,英格兰人在清理战争废墟时发现一个丹麦入侵者的头骨,出于愤恨,他 ...
- Java实现在线预览--openOffice实现
简介 之前有写了poi实现在线预览的文章,里面也说到了使用openOffice也可以做到,这里就详细介绍一下. 我的实现逻辑有两种: 一.利用jodconverter(基于OpenOffice服务)将 ...
- 深入理解JVM-内存溢出案例演示与分析
1.java堆溢出 思路:Java堆用于存储对象实例,只要不断地创建对象,并且保证GC Roots到对象之间有可达路径来避免垃圾回收机制清除这些对象, 那么在对象数量到达最大堆的容量限制后就会产生内存 ...
- python测试开发django-42.xadmin自定义菜单项
前言 xadmin后台的菜单项是放到一个app下的,并且里面的排序是按字母a-z排序,有时候我们需要划分多个项,需要自定义菜单列表,可以通过重写CommAdminView类实现.xadmin后台提供了 ...
- Python with语句和__enter__、__exit__过程抽取思想
with语句的应用场景 编程中有很多操作都是配套使用的,这种配套的流程可以称为计算过程,Python语言为这种计算过程专门设计了一种结构:with语句.比如文件处理就是这类计算过程的典型代表. 使 ...
- PEP 8016-Python之父重回决策层
PEP 8016-Python之父重回决策层 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 去年,技术社区里还发生了一件大事:Linux 之父 Linus Torvalds 宣 ...
- Kotlin函数与Lambda表达式深入
Kotlin函数: 关于Kotlin函数在之前也一直在用,用fun来声明,回忆下: 下面再来整体对Kotlin的函数进行一个学习. 默认参数(default arguments): 先来定义一个函数: ...
- docker学习5-docker安装tomcat环境和部署war包
前言 tomcat部署web项目非常方便,把war包放到webapps目录就可以了.本篇使用docker快速搭建一个tomcat环境 下载tomcat镜像 拉取官方最新版tomcat镜像 [root@ ...
- 项目Alpha冲刺--8/10
项目Alpha冲刺--8/10 作业要求 这个作业属于哪个课程 软件工程1916-W(福州大学) 这个作业要求在哪里 项目Alpha冲刺 团队名称 基于云的胜利冲锋队 项目名称 云评:高校学生成绩综合 ...
- janusgraph-mgmt中的一些操作
关闭事务 mgmt = graph.openManagement(); ids = mgmt.getOpenInstances(); for(String id : ids){if(!id.conta ...