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')

        }

    }

})

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

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。