当前位置:   article > 正文

动态菜单和按钮控制-前端权限控制-RBAC模型_rbac前端怎么控制菜单

rbac前端怎么控制菜单
动态菜单和按钮控制-前端权限控制-RBAC模型

目录




内容

1、前文回顾

要实现动态菜单和按钮控制,需要菜单和按钮权限数据,这些我们在之前的博文中已实现。
相关博文如下:

  1. 层级菜单生成算法
  2. 菜单和按钮权限数据封装返回

2、动态菜单

2.1、原理

  1. 数据库中给不同用户赋予不同的菜单权限,
  2. 用户登录获取菜单列表
  3. 前端路由加载菜单

2.2、对比发现问题

菜单的生成依赖与前端路由控制。

  • 框架默认路由对象:

      {
      	path: "/zip",
      	component: Layout,
      	redirect: "/zip/download",
      	alwaysShow: true,
      	name: "Zip",
      	meta: { title: "压缩", icon: "zip" },
      	children: [
      	  {
      		path: "download",
      		component: () => import("@/views/zip/index"),
      		name: "ExportZip",
      		meta: { title: "导出压缩" }
      	  }
      	]
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
  • 后端返回的菜单对象:

      {
      	"id": "1352785556979511297",
      	"name": "companyList",
      	"path": "companyList",
      	"type": 1,
      	"orderNum": 1,
      	"pid": "1352785556979511296",
      	"hidden": false,
      	"meta": {
      	  "icon": "company",
      	  "title": "公司管理"
      	}
       }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

小伙伴们发现了什么不吗?

  1. 是的我们自己构造的菜单对象中缺少路由对应的组件,即component属性。我们需要在控制动态菜单生成的地方自己构建。
  2. 原有路由是通过菜单对象 meta{roles: [角色]}实现动态菜单,而我们通过用户具有的菜单权限来控制。

通过查找我们发现路由对象数组生成方法为generateRoutes,方法位于@/store/modules/permission.js中。

2.3 改造

  • 代码如下:

      generateRoutes({ commit }, menus) {
      	return new Promise(resolve => {
      	  // let accessedRoutes
      	  // if (roles.includes('admin')) {
      	  //   accessedRoutes = asyncRoutes || []
      	  // } else {
      	  //   let accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
      	  // // }
      	  // 生成路由
      	  let accessedRoutes
      	  menus.forEach(v => {
      		v.component = Layout
      		if(v.children && v.children.length > 0) {
      		  v.children.forEach(c => {
      			c.component = (resolve) => require(["@/views/" + v.name + "/" + c.name],resolve)
      		  })
      		  // "@/views/" + v.name + "/" + c.name
      		}
      	  })
      	  accessedRoutes = menus
      	  commit('SET_ROUTES', accessedRoutes)
      	  resolve(accessedRoutes)
      	})
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
  • 解析:

    • 原有component通过import 来动态烂加载路由组件,这里我们构建后会报错,具体原理不是很清楚,我们改又ES5语法require实现

3、按钮控制

3.1、原理

  1. 数据库不同用户赋予不同的按钮权限-字符串标志
  2. 用户登录获取按钮权限数组
  3. 判断是否又权限,按钮组件v-if来控制显示与否

3.2、实现

因为登录之后又很多页面,每个页面又很多的按钮,而判断逻辑都一样,所有我们把判断逻辑封装为方法,挂在到Vue示例上,具体代码如下:

import store from './store'
...
Vue.prototype.$hasPerm = (perm) => {
  let btns = store.getters.btns
  if (btns && btns.length > 0) {
   return btns.includes(perm)
  }
  return false
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

这里简单列举一个按钮示例:

 <el-button
		class="filter-item"
		style="margin-left: 10px;"
		type="primary"
		icon="el-icon-edit"
		@click="handleCreate"
		v-if="$hasPerm('sys:company:save')"
	  >
		添加
</el-button>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

4、效果展示与问题

4.1、效果展示

  • 管理员用户登录界面:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GpWvi7YQ-1611749770257)(./images/2021-01-27_ret-auth-admin.png)]

  • 其他某个用户登录:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lSQA8v9U-1611749770266)(./images/2021-01-27_ret-auth-normal.png)]

4.2、问题

  1. main.js作为入口,代码越简洁越好,我们把判断按钮显示与否的方法写在main.js中
  2. 按钮权限控制,我们是在具体的每个按钮组件处判断,且与权限标志字符串,比如’sys:company:save’耦合在一起,不利于后期修改

问题2暂时没想到比较好的解决办法,问题1后面有空优化以下。其中非重要的页面列表和详情,默认所有用户都可以查看,即没有加权限。

后记

本项目为参考某马视频开发,相关视频及配套资料可自行度娘或者联系本人。上面为自己编写的开发文档,持续更新。欢迎交流,本人QQ:806797785

后端JAVA源代码地址:https://gitee.com/gaogzhen/ihrm-parent    // 后端项目
前端项目源代码地址:https://gitee.com/gaogzhen/ihrm-vue    // 前端后台管理系统
  • 1
  • 2
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/448008
推荐阅读
相关标签
  

闽ICP备14008679号