第一种:基于角色Role的动态路由管理 (不推荐,但市场用的比较多)

首先列出枚举每个角色对应几个路由,然后根据用户登录的角色遍历枚举出来的角色动态注册对应的路由

const roles = {
    admin:['所有路由'],
    '经理':['10个路由'],
    '运营':['5个路由'],
    '前台':['2个路由']
	'新增一个角色':[xxx] ===>改代码重新发布版本
 

这种做法一个弊端:每添加一个角色,都要手动添加代码key:value。最后前端又要发布新的版本(有解决方案如下)

这种方法大致流程如下:

登录:登录验证通过之后后台会返回一个token给前端,前端会保存在vuex和本地(防止刷新丢失登录状态),然后拿token去后台请求一个userInfo的接口获取用户信息(用户名,权限信息等等)

权限验证:通过token获取用户role信息,然后根据用户role算出对应应有权限信息的路由,最后用router.addRotes动态挂载计算出的路由。

代码的实现:

根据token拿到用户信息(权限信息)

这里代码过于简单就不写了,就是请求后台的数据而已。

请求回来的数据保存在Vuex当中(actions发请求----mutations传数据给state,过程不书写了)

//箭头函数
const getDefaultState = () => {
  return {
    //获取token
    token: getToken(),
    //存储用户名
    name: '',
    //存储用户头像
    avatar: '',
    //服务器返回的菜单信息【根据不同的角色:返回的标记信息,数组里面的元素是字符串】
    routes: [],
    //角色信息
    roles: [],
    //按钮权限的信息
    buttons: [],
 

vuex查看数据:保存成功

在获取用户信息的时候异步路由和服务器返回的路由进行对比。commit要提交对比好的路由,所有写一个对比路由函数。computedAsyncRoutes()函数第一个参数是异步路由,第二个是服务器返回的路由。

在actions外面定义一个对比路由的computedAsyncRoutes函数:

//定义一个函数:两个数组进行对比,对比出当前用户到底显示哪些异步路由
const computedAsyncRoutes = (asyncRoutes, routes) => {
  //过滤出当前用户【超级管理|普通员工】需要展示的异步路由
  return asyncRoutes.filter(item => {
    //数组当中没有这个元素返回索引值-1,如果有这个元素返回的索引值一定不是-1 
    if (routes.indexOf(item.name) != -1) {
      //递归:别忘记还有2、3、4、5、6级路由
      if (item.children && item.children.length) {
        item.children = computedAsyncRoutes(item.children, routes);
      return true;
 

commit的时候对比好路由(需要深拷贝一下,不然对比后数据影响原数据)

<template>
       <el-button type="primary" v-if="$store.state.user.buttons.indexOf('btn.Add1')!=-1">添加按钮1</el-button>
       <el-button type="primary"  v-if="$store.state.user.buttons.indexOf('btn.Add2')!=-1">添加按钮2</el-button>
</template>

第二种:基于菜单Menu的动态路由管理(推荐)

我这里是从0搭建的,很多细节需要自己处理,看起来比上面的方法麻烦其实不是这样的,上面是使用vue-admin很多细节作者已经处理好了,我这里需要自己处理,也更好的理解各种细节问题。
  • userMenus =>动态展示菜单

  • 用户管理 ----商品管理----角色管理等等这些路由模块映射成一个对象然后和后端返回这个角色的菜单信息进行对比,然后用Router.addRotes的API动态注册路由。

大致流程:(Vue3+TS+pinia实现)

这里的后台和上面的返回格式不一样,问题也不大。首页还是拿到token,用token拿用户信息,用户信息中有用户id,那个用户id去后台拿菜单信息。

然后进行路由对比,对比好就动态注册路由,要点击登录前就要计算好路由,也就是说push到首页就要算好路由,所有在login中actions进行对比,但是这个逻辑比较多,为了方便管理对比路由函数写在utils

在utils中:

这里用了两个for循环因为这里明确知道两次目录,要是children两层以上可以用递归

但是目前有一个问题就是,我注册权限路由是pinia的actions在点击登录按钮的回调进行注册的,现在当我刷新的时候这些路由就访问不到了,只能访问不用权限的路由,为什么会这样?

因为刷新不会重新加载pinia的actions的登录的回调,只有点击登录才会执行,解决办法就是刷新让这个回调重新执行一遍。具体实现如下:

  1. 在actions在定一个函数

第一种:基于角色Role的动态路由管理。登录:登录验证通过之后后台会返回一个token给前端,前端会保存在vuex和本地(防止刷新丢失登录状态),然后拿token去后台请求一个userInfo的接口获取用户信息(用户名,权限信息等等)权限验证:通过token获取用户role信息,然后根据用户role算出对应应有权限信息的路由,最后用router.addRotes动态挂载计算出的路由。 1.用户填写完账号和密码后向服务端验证是否正确,验证通过之后,服务端会返回一个token。 2.拿到token之后将这个token存起来,保证刷新页面后能记住用户登录状态,根据token去调用userInfo的接口来获取用户的详细信息(如用户权限,用户名等等信息)。 3.权限验证:通过token获取用户对应的权限,将请求的权限数组和用户信息存储到vuex中 ,动态根据用户的权限通过处理得到其对应有权限的路由,通过 router.addRoutes 动态添加这些路由。 一、登录: 登录成功后
一个系统包含众多模块,要求能够通过权限管理,控制不同用户对模块的访问权限,而且需要控制到对某个模块的某个操作(增删改查)的级别。一般情况下,通过角色对用户进行统一授权,在某些特殊情况下,能够单独对用户进行授权。         一、给用户分配角色。涉及到的模块有:        角色和用户的关系:以用户为主来进行设计符合客户的使用习惯,即将多个角色授予某个用户,也就是用户拥有多个
场景:不同的用户具有不同的权限,如只有vip用户可以享受高速下载服务,只有svip用户才可以享受极速下载服务。 思路:为用户添加角色,通过为角色添加权限从而达到权限控制的目的。 数据表构建 代码实现 model模型类: from datetime import datetime from django.db import models from django.contrib.auth.models import AbstractUser class UserProfile(Abstract 权限是用户可以访问的资源,包括页面权限、操作权限、数据权限 页面权限:即用户登录系统可以看到的页面,由菜单控制,菜单包括 一级菜单和二级菜单,只要用户有一级和二级菜单的权限,那么用户就可以访问页面; 操作权限:即页面的功能按钮,包括查看、新增、修改、删除、审核等。有的系统要求“可见即可操作“,意思是如果页面上能够看到操作按钮,那么用户就可以操作,要实现此需求,这里就需要前端来配合,前端开发把用户的权限信息缓存,在页面判断用户是否包含此权限,如果有,就显示该按钮,如...
用户权限管理实现 在项目的开发中,常为不同的用户设置不同的角色,以使得不同的用户拥有不同的功能,例如: 1、给张三赋予“人力资源经理”角色,“人力资源经理”具有“查询员工”、“添加员工”、“修改员工”和“删除员工”权限。此时张三能够进入系统,则可以进行这些操作; 2、去掉李四的“人力资源经理”角色,此时李四就不能够进入系统进行这些操作了。 用户权限管理的 Spark中的两种核心shuffle分别是: 1. Hash Shuffle:基于哈希算法进行的洗牌,将数据按照key的哈希值分发到不同的节点。这种方式可以实现数据的随机性,但是在处理大规模数据时会造成大量内存开销。 2. Sort Shuffle:基于排序算法进行的洗牌,将数据进行排序后再进行分发。这种方式可以保证数据的有序性,并且相较于Hash Shuffle来说,内存开销较小。但是在处理数据的时候需要进行排序操作,所以比Hash Shuffle要慢一些。