vue中的权限控制

什么是权限控制

在项目中,尤其是在后台管理系统中,不同人员登陆,看到的页面菜单是不一样的,比如,一个公司的办公系统,老板登陆可以看到所有的页面,而普通员工登录可能无法看到公司业绩,营收情况的页面,比如公司的员工个人资料页面只有人力资源部门有权利看,其他部门的员工是不允许查看公司员工信息数据的。当然了除了页面的权限,还会有一些按钮级别的权限,比如一个下载按钮,有的帐号可以用,有的人不能用,比如学校的系统,一个页面中有一个确认成绩按钮,这个按钮只有老师有权利点击,其他学生登陆是无法点击的。

所以权限控制基本可以总结为两种情况

	1.页面级的权限(用户是否有权限能看到这个页面)
	2.按钮级的权限(用户是否能看到或者能用页面中的某个按钮)

页面级权限控制(一)

1.后端返回路由信息,前端存储完整路由表

前端拿到路由信息采取递归的方式动态生成页面菜单。自己本身的router.js文件定义好页面所有的路由。这种方式弊端很明显,并不能实现真正的权限控制,因为如果用户记住了某个理由,用户不点击菜单,直接在地址栏里输入地址,那么页面还是可以显示出来

2.后端返回路由权限名,前端存储完整路由权限表,并动态生成路由(真正的权限控制)

首先前端router.js文件存储的路由配置信息会分为两部分,分别是需要权限的和不需要权限的。
页面一开始不能一个路由没有,所以会有一些不需要权限的页面,比如登录页,404页面等。所以一开始直接渲染
这个不需要权限的路由表,等后台返回之后再把需要权限的路由加到当前路由里面形成一个全新的路由表就可以了

router.js 不需要权限的路由表

 const route = [
  {
    
    
    path: '/',
    redirect: '/login',
  },
  {
    
    
    path: '/login',
    name: '登录页面',
    component: ()=>import("@/views/login.vue")
  },
  {
    
    
    path: '/404',
    name: '404页面',
    component: ()=>import("@/views/404.vue")
  },
]

router.js 需要权限的路由表
对于需要权限的页面,我们在路由中的meta属性里添加了一个字段roles,表示当前路由所需要的权限.
注意这个roles并不是关键字,叫别的名字也行。至于meta为什么值是一个数组,是我们考虑到将来有些页面可能不同的权限都能看,比如普通用户,管理员,超级管理员

export const asyncRouterMap = [
  {
    
    
    path: '/permission',
    name: 'permissionhome',
    meta: {
    
    
      icon: 'el-icon-setting',
      roles: ['admin','superadmin']
    },
    component: ()=>import("@/views/permission.vue")
 },
 {
    
    
    path: '/detail',
    name: 'detail',
    meta: {
    
    
      icon: 'el-icon-setting',
      roles: ['superadmin']
    },
    component: ()=>import("@/views/detail.vue")
 },

当用户登录之后,登陆接口会返回一个权限名字的字符串类似于如下结构

{
    
    
  code:200,
  success:true,
  result:{
    
    
    name:"张三",
    opid:11024,
    role:"admin"//此字段是拥有的权限名字
  }
}

拿到这个权限名字之后,去循环我们写好的那个需要权限的路由表进行挨个比较,

登录之后拿到的信息我们一般会存储在vuex中,因为这个数据全局都需要使用。具体怎么放到vuex中和怎么取出不做详细描述,基础差的先去学习vuex

新建一个js文件
具体操作就是引入我们的异步路由表,然后做一个循环

import  {asyncRouterMap} from "../router.js".

利用filter方法过滤出路由列表中role权限中跟我们返回的role权限名一致的项

asyncRouterMap.filter()

将筛选之后的路由表,通过一个方法加入到当前项目的路由中。通过调用根路由实例的这个方法,就可以实现把任意一个路由配置加入到当前页面路由中,由此就可以生成一个新的路由。达到了真正控制权限的目的

router.addRoutes(筛选之后的路由表)

页面级权限控制(二)

第二种方式其实就是第一种方式的简化版,只不过后端返回的不是返回权限名字了,我们前端也不在本地存储异步路由表了,登陆成功之后直接由后端返回异步路由表,然后前端直接通过addRoutes方法添加。

这种方式好处是减少了前端工作量,但是实际工作比较麻烦,前端每次要加权限都需要让后端帮助添加, 因为路由表是在后端维护的。

按钮级权限控制(一)

比如某个按钮只有超级管理员能看到,其他权限看不到,那么按照上面第一种说法,我们从返回信息拿到role字段
那么页面中的按钮可以这么写

html

<button v-if="role=='superAdmin'">权限按钮</button>

js

export default{
    
    
	computed:{
    
    
		//当然实际工作中这里一般都使用mapState
		role:this.$store.state.role
	}
}

这样其实就能实现按钮级别的权限控制。特殊情况如果role是数组,那么可以用indexOf方法去查找一下权限数组中包不包含我这个按钮需要的权限,原理几乎不变

按钮级权限控制(二)

第二种方式是通过自定义指令,原理大致相同

1.首先还是取出后端返回的权限的名字
2.全局定义一个自定义指令


Vue.directive('per', {
    
    
    bind: (el, binding, vnode) => {
    
    
    //roles是我们的权限数组,binding.value是我们传入自定义指令的值
    //如果找不到,那证明没有权限,把当前元素节点移除掉
        if (roles.indexOf(binding.value)==-1) {
    
    
            el.parentNode.removeChild(el);
        }
    }

使用

//这个传入的admin是对应上面binding.value
<div v-per="[admin]">
    admin 可见
</div>

下面是官网对于自定义指令的语法介绍,可以参照。
具体地址 https://cn.vuejs.org/v2/guide/custom-directive.html

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_40096030/article/details/114363331