IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 在Vue中使用RBAC权限设计思想实现根据角色不同的权限展现不用的页面和按钮 -> 正文阅读

[JavaScript知识库]在Vue中使用RBAC权限设计思想实现根据角色不同的权限展现不用的页面和按钮

RBAC是什么?

RBAC(Role-Based Access control)权限模型 ,也就是基于角色的权限分配解决方案,在RBAC中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限,这就极大地简化了权限的管理。这样的管理都是层级相互依赖的,权限赋予给角色,而把角色又赋予用户,这样的权限设计很清楚,管理起来很方便

三个关键点:

用户: 就是使用系统的人(员工)

权限点:这个系统中有多少个功能(例始:有3个页面,每个页面上的有不同的操作)

角色:不同的权限点的集合

一、权限应用:动态生成左侧菜单栏的菜单(利用addRoutes()方法)

思路:当用户点击登录以后,首先进入路由守卫,在路由守卫中,获取用户的信息包括用户权限,在vuex中保存菜单信息,然后运用addRoutes()方法动态添加路由配置,最后完成登录功能,然后用户就可以看到在自己权限范围内显示的页面和功能

补充:addRourtes()对象的格式

router.addRoutes([路由配置对象])
或者:
this.$router.addRoutes([路由配置对象])

?动态添加路由配置

(1)首先要把router文件夹里面添加的动态路由的配置删除掉

const createRouter = () =>
  new Router({
    // 控制路由滚动行为,滚动到顶部
    // mode: 'history', // require service support
    scrollBehavior: () => ({ y: 0 }),
    // 最终生成的路由配置:动态+静态
   - // routes: [...constantRoutes, ...asyncRoutes]
   + routes: [...constantRoutes]
  })

(2)在路由守卫中在有token时,使用addRourtes(),添加动态路由

router.beforeEach(async (to, from, next) => {
  const token = store.state.user.token
  // console.log(token)
  if (token) {
    if (to.path === '/login') {
      // 有token ,还去登录——>直接去主页
      next('/')
    } else {
      if (!store.getters.userId) {
        await store.dispatch('user/getProfile')
        // 通过assRoutes添加用户可以访问的页面
        // 过滤掉没有权限的页面
        const menus = store.state.user.userInfo.roles.menus
        const filterRouters = asyncRoutes.filter(item => {
          return menus.includes(item.children[0].name)
        })
        router.addRoutes(filterRouters)
      
      } 
        next()
      
      
    }

(3)这样配置的动态路由后,会遇到一个问题就是,在地址栏输入地址可以访问对应的页面,但是在菜单栏看不到动态路由

原因分析:当前的菜单渲染使用的数据:this.$router.options.routes 这个数据是固定,我们通过addRoutes添加的路由表只存在内存中,并不会改变this.$router.options.routes

解决这个问题的办法,在vuex中保存静态路由和动态路由

// 导入静态路由
import { constantRoutes } from '@/router'
export default {
namespaced: true,
state: {
// 先以静态路由作为菜单数据的初始值
menuList: [...constantRoutes]
},
mutations: {
setMenuList(state, asyncRoutes) {
// 将动态路由和静态路由组合起来
state.menuList = [...constantRoutes, ...asyncRoutes]
}
}
}

然后提交setMenuList生成完整的菜单数据,修改导航守卫中的代码

router.beforeEach(async (to, from, next) => {
  const token = store.state.user.token
  // console.log(token)
  if (token) {
    if (to.path === '/login') {
      // 有token ,还去登录——>直接去主页
      next('/')
    } else {
      if (!store.getters.userId) {
        await store.dispatch('user/getProfile')
        // 通过assRoutes添加用户可以访问的页面
        // 过滤掉没有权限的页面
        const menus = store.state.user.userInfo.roles.menus
        const filterRouters = asyncRoutes.filter(item => {
          return menus.includes(item.children[0].name)
        })
         // 保存到vuex
       + store.commit('menus/setMenuList', filterRouters)
        router.addRoutes(filterRouters)
      
      } 
        next()
      
      
    }

同时,还要修改菜单生成部分改写使用vuex中的数据

routes() {
  // 拿到的是一个完整的包含了静态路由和动态路由的数据结构
- // return this.$router.options.routes
+ return this.$store.state.menu.menuList
}

(4)这样设置动态路由以后页面仍然存在一些bug

1、bug1:一刷新页面白屏的bug

解决bug的方案:把404页改到路由配置的最末尾就可以了

从route/index.js中的静态路由中删除 path:'*'这一项



// 不需要特殊的权限控制就可以访问的页面
export const constantRoutes = [
{
path: '/login',
component: () => import('@/views/login/index'),
hidden: true
},
// 404 page must be placed at the end !!!
- { path: '*', redirect: '/404', hidden: true }
]

在permission.js中补充在最后

router.beforeEach(async (to, from, next) => {
  const token = store.state.user.token
  // console.log(token)
  if (token) {
    if (to.path === '/login') {
      // 有token ,还去登录——>直接去主页
      next('/')
    } else {
      if (!store.getters.userId) {
        await store.dispatch('user/getProfile')
        // 通过assRoutes添加用户可以访问的页面
        // 过滤掉没有权限的页面
        const menus = store.state.user.userInfo.roles.menus
        const filterRouters = asyncRoutes.filter(item => {
          return menus.includes(item.children[0].name)
        })
      + // 把404添加到最后面
        const page404 = { path: '*', redirect: '/404', hidden: true }
        filterRouters.push(page404)
         // 保存到vuex
        store.commit('menus/setMenuList', filterRouters)
        router.addRoutes(filterRouters)
     + next({
          ...to,
          replace: true
        })
      
      } else{
         next()
      }
          
    }

2、bug2:退出后,再次登陆,发现菜单异常 (控制台有输出说路由重复);

?

原因

路由设置是通过router.addRoutes(filterRoutes)来添加的,退出时,并没有清空,再次登陆,又加了一次,所以有重复。

需要将路由权限重置 (恢复默认) 将来登录后再次追加才可以,不然的话,就会重复添加

?解决方案:在router/index.js文件,有一个重置路由方法resetRouter(),这个方法就是将路由重新实例化,相当于换了一个新的路由,之前加的路由就不存在了,需要在登出的时候, 调用一下即可,所以,在在store/modules/user.js中调用这个方法

import { resetRouter } from '@/router/index.js'
// 清空信息
    async userLogout(store) {
      // console.log(res)
      // 清除token
      store.commit('removeToken')
      // 清除用户信息
      store.commit('setUserInfo', {})
      resetRouter()
    },

权限应用-按钮级控制

可以通过自定义指令实现按钮级的控制

(1)实现方案一:在main.js中自定义指令

// 自定义指令
Vue.directive('allow', {
  // inserted被绑定的元素插入dom时自动执行
  inserted: function(el, binding) {
    // el dom对象
    const points = store.state.user.userInfo.roles.points
    if (points.includes(binding.value)) {
      // console.log(binding.value)
      // 显示展示元素
    } else {
      // 不显示元素(不安全)
      // el.style.display = 'none'
      // 不要有这个元素,销毁掉元素
      el.parentNode.removeChild(el)
    }
  }
})

在页面的按钮就可以使用v-allow指令,从而根据角色的权限不同从而实现按钮的显示或隐藏

<el-button v-allow="'export_excel'" type="danger" size="small">导出excel</el-button>

(2)实现方案一:利用v-if

  <el-button v-if="$store.state.user.userInfo.roles.points.includes('import_excel')"
          type="warning size="small">导入excel</el-button>

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-31 15:22:02  更:2021-08-31 15:22:18 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/27 19:26:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计