动态菜单和按钮控制-前端权限控制-RBAC模型
目录
内容
1、前文回顾
要实现动态菜单和按钮控制,需要菜单和按钮权限数据,这些我们在之前的博文中已实现。
相关博文如下:
2、动态菜单
2.1、原理
- 数据库中给不同用户赋予不同的菜单权限,
- 用户登录获取菜单列表
- 前端路由加载菜单
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: "导出压缩" } } ] }
-
后端返回的菜单对象:
{ "id": "1352785556979511297", "name": "companyList", "path": "companyList", "type": 1, "orderNum": 1, "pid": "1352785556979511296", "hidden": false, "meta": { "icon": "company", "title": "公司管理" } }
小伙伴们发现了什么不吗?
- 是的我们自己构造的菜单对象中缺少路由对应的组件,即component属性。我们需要在控制动态菜单生成的地方自己构建。
- 原有路由是通过菜单对象 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) }) }
-
解析:
- 原有component通过import 来动态烂加载路由组件,这里我们构建后会报错,具体原理不是很清楚,我们改又ES5语法require实现
3、按钮控制
3.1、原理
- 数据库不同用户赋予不同的按钮权限-字符串标志
- 用户登录获取按钮权限数组
- 判断是否又权限,按钮组件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
}
这里简单列举一个按钮示例:
<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>
4、效果展示与问题
4.1、效果展示
-
管理员用户登录界面:
-
其他某个用户登录:
4.2、问题
- main.js作为入口,代码越简洁越好,我们把判断按钮显示与否的方法写在main.js中
- 按钮权限控制,我们是在具体的每个按钮组件处判断,且与权限标志字符串,比如’sys:company:save’耦合在一起,不利于后期修改
问题2暂时没想到比较好的解决办法,问题1后面有空优化以下。其中非重要的页面列表和详情,默认所有用户都可以查看,即没有加权限。
后记 :
本项目为参考某马视频开发,相关视频及配套资料可自行度娘或者联系本人。上面为自己编写的开发文档,持续更新。欢迎交流,本人QQ:806797785
后端JAVA源代码地址:https://gitee.com/gaogzhen/ihrm-parent // 后端项目
前端项目源代码地址:https://gitee.com/gaogzhen/ihrm-vue // 前端后台管理系统