文章目录
- 一、重要知识点总结以及登录功能实现
- 二、权限管理菜单的增删改查实现
-
- 1. 路由配置
- 2. 用户管理功能
-
- 2.1 后端接口API介绍
- 2.2 前端api接口
- 2.3 页面和逻辑编写
- 3. 角色管理功能
-
- 4. 菜单管理功能
-
- 三、权限控制功能实现
-
- 1. 拆分路由
- 2. 将用户角色和菜单权限保存到vuex,然后过滤路由
- 3. 使用模板需要做的额外更改
- 4. 解决刷新页面vuex中数据丢失,路由丢失问题
- 四、按钮权限控制
-
- 1. 修改element ui 源码解决问题
- 2. 实现按钮权限
管理系统后端(java)请参考:https://blog.csdn.net/grd_java/article/details/121925792 |
本项目源码,码云:https://gitee.com/yin_zhipeng/vue-backstage-scaffolding.git |
一、重要知识点总结以及登录功能实现
由于篇幅原因,我将其放在这个文章中:https://blog.csdn.net/grd_java/article/details/122770777 |
二、权限管理菜单的增删改查实现
我们先实现整个的增删改查功能,最后再实现权限功能,很简单,直接看上面码云源码就好,下面是效果演示 |
- 用户管理
- 角色管理
- 菜单管理
1. 路由配置
先把相关组件创建完成,创建出来就好,把首页的index.vue文件复制3份即可 |
export const constantRoutes = [
{
path: '/login',
component: () => import('@/views/login/index'),
hidden: true
},
{
path: '/404',
component: () => import('@/views/404'),
hidden: true
},
{
path: '/',
component: Layout,
redirect: '/dashboard',
children: [{
path: 'dashboard',
name: 'Dashboard',
component: () => import('@/views/dashboard/index'),
meta: { title: '首页', icon: 'dashboard' }
}]
},
{
path: '/security',
component: Layout,
redirect: '/security/user',
meta: { title: '权限管理', icon: 'el-icon-lock' },
children: [
{
path: 'user',
name: 'User',
component: () => import('@/views/security/user/index'),
meta: { title: '用户管理'}
},
{
path: 'role',
name: 'Role',
component: () => import('@/views/security/role/index'),
meta: { title: '角色管理'}
},
{
path: 'menu',
name: 'menu',
component: () => import('@/views/security/menu/index'),
meta: { title: '菜单管理'}
},
]
},
{ path: '*', redirect: '/404', hidden: true }
]
2. 用户管理功能
2.1 后端接口API介绍
- 根据所传json,查询符合条件的用户,json为空,显示所有,post请求.另外,还提供了一个处理分页的接口,也可以查询符合条件的用户
- put请求,表示根据json修改用户,但是不会修改密码
- put请求,根据用户id和密码,修改用户密码
- delete请求,根据id删除用户
- put请求,更新用户所有角色,uid为用户id,rids是一个数组,表示角色,这里选择的角色将成为指定用户的角色
- post请求,添加用户
2.2 前端api接口
2.3 页面和逻辑编写
3. 角色管理功能
3.1 数据回显
如果当前用户拥有自己的菜单,我们点击修改菜单按钮后,需要将当前角色已有菜单,做数据回显,思路如下图 |
难点:回显后,用户操作数据,需要和回显数据结合。当用户没有点击确定修改按钮做什么处理 |
- 拿到当前用户id,先清除回显数据,然后请求数据,完成数据回显。这样用户没有点击修改按钮,下次进入,依然是实时数据
- 点击修改按钮
4. 菜单管理功能
除了处理树形数据有点难度外,其它大家自己去看源码就好 |
4.1 树形结构数据处理算法
export function treeData (source, id, pid, children, rootId) {
id = id || 'id'
pid = pid || 'pid'
children = children || 'children'
rootId = rootId || 0
const cloneData = JSON.parse(JSON.stringify(source))
return cloneData.filter(father => {
const branchArr = cloneData.filter(child => father[id] == child[pid])
branchArr.length > 0 ? father[children] = branchArr : delete father[children]
return father[pid] == rootId
})
}
export function unTreeData(source,children){
children = children || 'children'
let cloneData = JSON.parse(JSON.stringify(source))
let arr = []
unTreeDatadd(cloneData,children,arr)
return arr;
}
function unTreeDatadd(source,children,arr){
source.filter(father=>{
if(father[children]){
arr.push(father)
unTreeDatadd(father[children],children,arr)
delete father[children]
}else{
arr.push(father)
}
})
}
三、权限控制功能实现
- admin用户登录
- 作者用户登录
后端的针对url的已经完成了权限控制,所以我们前端不做任何实现,一个用户也没有办法操作它没有权限的内容(直接报权限不足异常)。但是这样用户体验不好,所以我们最好让一个用户没有权限操作的东西,直接不显示,思路如下: |
- 当用户登录成功后,根据用户id查询它拥有的角色,和菜单权限,保存到vuex中
- 将路由拆分(把原来完整的进行拆分)
- 常量路由:无论何种用户,都可以操作的路由,比如登录,首页。
- 异步路由:根据不同用户,展示不同的路由。
注意,路由不是从服务器获取到的,服务器返回的只是一个标识,我们需要进行比对,隐藏不需要的路由
- 任意路由:404等路由,用户操作错了,从定向的路由
- 获取异步路由,我们需要通过异步路由,进行比较过滤,判断哪些路由不需要显示
- 对于路由,我们主要通过查询数据库配置的菜单,取出path属性,与前端的路由进行比较,过滤前端的路由,path相同的路由,会显示,path不同的路由会被过滤
1. 拆分路由
2. 将用户角色和菜单权限保存到vuex,然后过滤路由
2. mutations方法,合并路由,挂载到router |
3. 获取用户信息成功后,获取用户菜单,将角色和菜单封装到vuex |
const compareasyncRoutes = (asyncRoutes,routes)=>{
return asyncRoutes.filter(item =>{
if(routes.indexOf(item.path)!=-1){
if(item.children&&item.children.length){
item.children = compareasyncRoutes(item.children,routes)
}
return true;
}
})
}
3. 使用模板需要做的额外更改
完成上面的内容后,已经完成了路由的权限控制,但是我们使用的模板,只使用了常量路由,所以我们需要修改 |
- 如下可看到,模板中使用的是常量路由
4. 解决刷新页面vuex中数据丢失,路由丢失问题
很简单,通过路由导航,切换路由时判断vuex中数据是否存在,如果不存在,说明刷新了页面,需要重新生成路由 |
if(store.state.user.routesResult.length === 0 ){
store.dispatch('user/getInfo').then(()=>{
next({path:to.path})
})
}else{
next()
}
四、按钮权限控制
如果用户可以浏览某页面,但是没有某按钮权限,那么将无法看到此按钮,效果如下: |
- 需要设定浏览权限(因为我们使用element ui组件,它没法直接选父菜单,)
- 超级管理员的权限
- 普通用户的权限
- 超级管理员看到的页面
- 普通用户看到的页面
1. 修改element ui 源码解决问题
我们上面通过人为多添加一个显示权限,解决了父菜单无法直接选中的问题 |
另外还可以修改element ui 源码,修改方法看下面注释,我这里选用上面的方法 |
2. 实现按钮权限
- 通过菜单权限来判断
- 只需要判断就可以了
<el-button type="primary" slot="reference" v-show="$store.state.user.buttons.indexOf('btn:security')!=-1">添加</el-button>
- 超级管理员看到的页面
- 普通用户看到的页面