vue中对于路由权限进行判断的几种方法(vue-element-admin)

由于element多用来做后端管理界面,所以这里给大家推荐一个用来做后端管理的element框架!(vue-element-admin)

直接进入主题:

1.对路由跳转进行判断,如果符合权限就允许,反之就不行

2.对跳转页面进行逻辑请求判断,就是页面数据需要一定的权限才能发送请求(这样需要后端人员给你做,个人感觉不太现实,后端估计想干你)

3.根据权限,动态生成对应的路由,什么权限拥有什么路由(vue-element-admin)就是这么做的,动态生成路由

常用方法一般都是:

 ----------- v-if + router.beforeEach() ----------

由于后端管理界面涉及到,对登陆用户的权限判断,可能做的好点的后端管理页面,要么把相对应的跳转事件进行隐藏或判断,或者把跳转页面进行隐藏,我之前也是这样做的,对跳转的路由按钮进行  v-if  判断,然后再在router.beforeEach()进行路由判断,这样就可以防止部分用户,根据请求地址来实现跳转

-------------对跳转的按钮事件进行权限判断-------------

这样就比第一种方法更直接,对跳转页面的路由事件,添加一个方法,然后根据权限判断,if和else,满足就跳转,不满足就return,如果想要提升一下用户体验度,就弹出一个消息提示框,说您暂无权限!这是不是更简单

这样的方法,最直观,最简单,也最方便!但是呢,用户体验度不是很好,而且权限是写死的,不具备灵活性,但是并不妨碍这是一种好方法!!

vue-element-admin根据权限动态生成路由的方式

学习了一下vue-element-admin这个后端管理框架后:我就觉得它的这种动态生成路由的方式很新颖,也很厉害,所以再踩了几个坑以后,就来记录一下

构建项目上:ts+vuex+cookie

思路:

第一步:

就是在你登陆以后,后端返回token,然后在请求成功的回调里面,又发送token去后端去获取当前用户的详细信息,信息中包括了你这名用户的权限,是否为管理员身份,还是次级管理员身份,然后将token存入cookie,将请求获取到的数据存入vuex!假设这个存储你权限的字段交roles,是个数组,类似:[’admin'] or ['Secondary'] 

第二步:

这里要说明的是,路由表中会定义两个路由表,一个为公共路由表,一个为动态路由表,公共路由表就是不需要权限也能去访问,动态路由表顾名思义就是需要权限去获取了!然后根据获取到你的权限之后,会根据roles中的字段,去遍历动态路由表中的对应的路由表,然后将符合条件的路由表保存起来


单个路由下面meta里面定义roles字段,和你获取到的权限尽量对应

第三步:最后将获取到的符合权限的路由,合并到固定路由下面,通过router.addRouter(),当然了这里还是要用到router.beforeEach()去做路由判断,让权限更牢靠一点

具体实现方法:贴代码

获取用户信息和权限

import { VuexModule, Module, Mutation, Action, getModule } from 'vuex-module-decorators'

import { login,UserInfo } from '../../api/user'

import { getCookie,setCookie } from '../../utils/cookies'

import store from '@/store'

export interface usermodel{

    username:string,

    password:string,

    token:string

}

@Module({ dynamic: true, store, name: 'user' })

class User extends VuexModule implements usermodel{

    public username = ""

    public password = ""

    public token = getCookie('token') ||""

    public roles:string[] = [] 

    @Mutation

    private SET_TOKEN(token:string){

        this.token = token

    }

    @Mutation

    private SET_ROLES(roles:string[]){

        this.roles = roles

    }

    @Mutation

    private SET_NAME(name:string[]){

        this.roles = name

    }

    @Action

    public async Login(userInfo:{username:string,password:string}){ //登陸獲取token

        let { username,password } = userInfo

        username = username.trim()

        const data = await login({username,password})

        const { token } = data as any

        setCookie('token',token)

        this.SET_TOKEN(token)

    }

    @Action

    public async getUserinfo(){ //根據token去獲取登陸用戶個人信息,判斷個人權限

        if(this.token == ""){

            console.log('token不存在或者已过期')

        }

        const {data} = await UserInfo(this.token)

        if(!data){

            throw Error('未查到此用户,请重新登陆')

        }

        const { roles,name } = data

        if(!roles || roles.length<=0){

            throw Error('您不属于管理员范畴')

        }

        this.SET_ROLES(roles)

        this.SET_NAME(name)

    }

}

export const UserModel = getModule(User)

根据权限筛选对应路由

import { VuexModule,Module,Action,Mutation,getModule } from 'vuex-module-decorators'

import { asyncRoutes,constantRoutes } from '@/router'

import store from '@/store'

import { RouteConfig } from 'vue-router'

export interface IpermissionState{

    routes:RouteConfig[],

    dynamicRoutes: RouteConfig[]

}

const hasPermission = (roles:string[],route:RouteConfig)=>{  //判断动态路由中的meta中是否包含你当前用户的权限

    if(route.meta && route.meta.roles) {

        return roles.some(role => route.meta.roles.includes(role))

    }else{

        return true

    }

}

export const filterAsyncRoutes = (routes:RouteConfig[],roles:string[]):any=>{  //递归查询出动态路由中符合当前用户权限的路由

    const res:RouteConfig[] = []

    routes.forEach(route => {

        const r = { ...route }

        if(hasPermission(roles,r)){

            if(r.children){

                r.children = filterAsyncRoutes(r.children,roles)

            }

            res.push(r)

        }

    });

}

@Module({ dynamic: true, store, name: 'permission' })

class Permission extends VuexModule implements IpermissionState{

    public routes:RouteConfig[] = []

    public dynamicRoutes:RouteConfig[] = []

    @Mutation

    private SET_ROLES(routes:RouteConfig[]){  //合并固定路由和动态路由

        this.routes = constantRoutes.concat(routes) //合并之后的所有的路由

        this.dynamicRoutes = routes //获取到的所有的动态的路由

    }

    @Action

    public GenerateRoutes(roles: string[]) {

        let accessedRoutes

        if(roles.includes('admin')){  //判断是否为管理员,如果是管理员就不用筛选路由,直接全部给出

            accessedRoutes = asyncRoutes

        }else{

            accessedRoutes = filterAsyncRoutes(asyncRoutes,roles)  //如果是次级管理员,就筛选出符合次级管理员的路由

        }

        this.SET_ROLES(accessedRoutes)

    }

}

export const PermissionModule = getModule(Permission)

将符合权限的路由添加到固定路由上

import router from './router'

import { Route } from 'vue-router'

import { UserModel } from './store/models/user'

import { PermissionModule } from './store/models/permission'

const whitelist = ['/login','/auth-redirect']

router.beforeEach(async(to:Route,form:Route,next:any)=>{

    if(UserModel.token){

        if(to.path === '/login'){

            next({path:'/'})

        }else{

            if(UserModel.roles.length === 0){

                try{

                    await UserModel.getUserinfo()  //调用获取用户信息的方法

                    const roles = UserModel.roles

                    PermissionModule.GenerateRoutes(roles)  //筛选出符合条件的路由

                    router.addRoutes(PermissionModule.dynamicRoutes) //添加路由

                    next({ ...to, replace: true })  //这是会清除浏览器中的历史记录

                }catch(err){

                    return console.log(err)

                }

            }else{

                next()

            }

        }

    }else{

        if(whitelist.indexOf(to.path) !== -1){

            next()

        }else{

            next('/login')

        }

    }

})

实现方法可能有些绕,有兴趣的小伙伴可以去官网下载源码去看看!多敲个两遍就知道了

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335