在权限设计时,分为部门、岗位、人员三部分, 人员下面挂部门,部门下面挂岗位,岗位下面挂菜单,用户在进行授权时,勾选了操作权限,默认数据权限也进行勾选。
权限组:查询、新增、修改、删除
用户交互如下:
1、选中新增、修改、删除中的任何一个复选框时,查询框也选中。
2、选中查询框时,新增、修改、删除不变。
3、取消选中查询框时,新增、修改、删除都取消选中。
代码如下:
- <div>
- <el-tree
- ref="treeRef"
- class="permission-tree"
- :data="menuTree"
- show-checkbox
- node-key="id"
- default-expand-all
- :expand-on-click-node="false"
- :check-on-click-node="true"
- @check="handleCheck"
- :props="{
- label: 'title'
- }"
- >
- el-tree>
- div>
-
- <script>
- export default {
- data() {
- return {
- menuTree: [
- {
- id: '1717148200757',
- code: 'departmentManagement',
- title: '部门管理 ',
- name: '部门管理 ',
- parentIdId: null,
- children: [
- {
- id: '1717148287418',
- parentIdId: '1717148200757',
- code: 'department',
- title: '部门',
- name: '部门 ',
- children: [
- {
- id: 'department:query',
- code: 'department:query',
- name: '查询',
- title: '查询',
- parentIdId: '1717148287418',
- dataPermission: true
- },
- {
- id: 'department:add',
- code: 'department:add',
- name: '新增',
- title: '新增',
- parentIdId: '1717148287418',
- dataPermission: false
- },
- {
- id: 'department:update',
- code: 'department:update',
- name: '修改',
- title: '修改',
- parentIdId: '1717148287418',
- dataPermission: false
- },
- {
- id: 'department:delete',
- code: 'department:delete',
- name: '删除',
- title: '删除',
- parentIdId: '1717148287418',
- dataPermission: false
- }
- ]
- }
- ]
- },
- {
- id: '1717148223729',
- code: 'jobManagement',
- title: '岗位管理',
- name: '岗位管理',
- parentId: null,
- children: [
- {
- id: '1717148366037',
- parentId: '1717148223729',
- code: 'jobInside',
- title: '岗位',
- name: '岗位',
- children: [
- {
- id: 'permissionManagement:position:query',
- code: 'permissionManagement:position:query',
- name: '查询',
- title: '查询',
- parentIdId: '1717148366037',
- dataPermission: true
- },
- {
- id: 'permissionManagement:position:add',
- code: 'permissionManagement:position:add',
- name: '新增',
- title: '新增',
- parentIdId: '1717148366037',
- dataPermission: false
- },
- {
- id: 'permissionManagement:position:update',
- code: 'permissionManagement:position:update',
- name: '修改',
- title: '修改',
- parentIdId: '1717148366037',
- dataPermission: false
- },
- {
- id: 'permissionManagement:position:delete',
- code: 'permissionManagement:position:delete',
- name: '删除',
- title: '删除',
- parentIdId: '1717148366037',
- dataPermission: false
- }
- ]
- }
- ]
- },
- {
- id: '1717148248870',
- code: 'userManagement',
- title: '用户管理',
- name: '用户管理',
- parentId: null,
- children: [
- {
- id: '1717148408202',
- parentId: '1717148248870',
- code: 'userAdmin',
- title: '用户',
- name: '用户',
- children: [
- {
- id: 'userAdmin:query',
- code: 'userAdmin:query',
- name: '查询',
- title: '查询',
- parentIdId: '1717148408202',
- dataPermission: true
- },
- {
- id: 'userAdmin:add',
- code: 'userAdmin:add',
- name: '新增',
- title: '新增',
- parentIdId: '1717148408202',
- dataPermission: false
- },
- {
- id: 'userAdmin:update',
- code: 'userAdmin:update',
- name: '修改',
- title: '修改',
- parentIdId: '1717148408202',
- dataPermission: false
- },
- {
- id: 'userAdmin:delete',
- code: 'userAdmin:delete',
- name: '删除',
- title: '删除',
- parentIdId: '1717148408202',
- dataPermission: false
- }
- ]
- }
- ]
- }
- ]
- };
- },
- methods: {
- /**
- * 复选框选中事件
- * 实现的效果:
- * 1、查询节点选中时,其相邻兄弟节点不变
- * 2、查询节点取消选中时,其相邻兄弟节点取消选中
- * 3、其相邻兄弟节点任何一个选中时,查询节点必选中
- * 注:查询节点 dataPermission:true
- * **/
- handleCheck(data) {
- if (!data.children) {
- // 获取当前叶子节点的兄弟节点
- const sublingsNode = this.getSiblingsById(this.menuTree, data.id);
- // 获取当前叶子节点中为查询节点的项
- const dataPermissionItem = [data, ...sublingsNode].find(
- (item) => item.dataPermission
- );
-
- if (data.dataPermission) {
- // 操作的是查询节点时,将其兄弟节点设置为取消选中状态
- sublingsNode.forEach((item) => {
- this.$refs.treeRef.setChecked(item, false);
- });
- } else {
- // 操作的是兄弟节点时,将查询节点设置为选中状态
- this.$refs.treeRef.setChecked(dataPermissionItem, true);
- }
- }
- },
-
- /**
- * 通过当前节点的 id 查找兄弟节点
- * treeData:树形结构的数据源
- * nodeId:当前节点的 id
- * **/
- getSiblingsById(treeData, nodeId) {
- function findSiblings(nodes) {
- for (const node of nodes) {
- if (node.id === nodeId) {
- return nodes.filter((item) => item.id !== nodeId);
- }
- if (node.children) {
- const siblings = findSiblings(node.children, node.id);
- if (siblings) return siblings;
- }
- }
- return null;
- }
-
- return findSiblings(treeData, null);
- }
- }
- };
- script>
总结:
在写这部分逻辑时,难点在于取消数据权限时,怎么将操作权限也进行取消,这部分的交互相当于是查询是新增、修改、删除的取消全选操作。在进行这部分交互效果实现时,有考虑过使用 current-change 这个事件,因为这个事件可以获取到一个 Node 对象,在 Node 对象中可以获取到当前节点父节点,从而在父节点下找到当前节点及兄弟节点,从而避免了使用递归的方式查找兄弟节点,这个事件有个问题,无法触发 check 事件,导致在点击复选框选中时,事件未触发,所以退而求其次考虑使用 check 事件,配合递归方法实现最终的交互效果。
补充:
可以将递归函数去掉,使用 elementUI 中提供的 getNode 方法获取当前节点的兄弟节点,修改如下:
- <div>
- <el-tree
- ref="treeRef"
- class="permission-tree"
- :data="menuTree"
- show-checkbox
- node-key="id"
- default-expand-all
- :expand-on-click-node="false"
- :check-on-click-node="true"
- @check="handleCheck"
- :props="{
- label: 'title'
- }"
- >
- el-tree>
- div>
-
- <script>
- export default {
- data() {
- return {
- menuTree: [
- {
- id: '1717148200757',
- code: 'departmentManagement',
- title: '部门管理 ',
- name: '部门管理 ',
- parentIdId: null,
- children: [
- {
- id: '1717148287418',
- parentIdId: '1717148200757',
- code: 'department',
- title: '部门',
- name: '部门 ',
- children: [
- {
- id: 'department:query',
- code: 'department:query',
- name: '查询',
- title: '查询',
- parentIdId: '1717148287418',
- dataPermission: true
- },
- {
- id: 'department:add',
- code: 'department:add',
- name: '新增',
- title: '新增',
- parentIdId: '1717148287418',
- dataPermission: false
- },
- {
- id: 'department:update',
- code: 'department:update',
- name: '修改',
- title: '修改',
- parentIdId: '1717148287418',
- dataPermission: false
- },
- {
- id: 'department:delete',
- code: 'department:delete',
- name: '删除',
- title: '删除',
- parentIdId: '1717148287418',
- dataPermission: false
- }
- ]
- }
- ]
- },
- {
- id: '1717148223729',
- code: 'jobManagement',
- title: '岗位管理',
- name: '岗位管理',
- parentId: null,
- children: [
- {
- id: '1717148366037',
- parentId: '1717148223729',
- code: 'jobInside',
- title: '岗位',
- name: '岗位',
- children: [
- {
- id: 'permissionManagement:position:query',
- code: 'permissionManagement:position:query',
- name: '查询',
- title: '查询',
- parentIdId: '1717148366037',
- dataPermission: true
- },
- {
- id: 'permissionManagement:position:add',
- code: 'permissionManagement:position:add',
- name: '新增',
- title: '新增',
- parentIdId: '1717148366037',
- dataPermission: false
- },
- {
- id: 'permissionManagement:position:update',
- code: 'permissionManagement:position:update',
- name: '修改',
- title: '修改',
- parentIdId: '1717148366037',
- dataPermission: false
- },
- {
- id: 'permissionManagement:position:delete',
- code: 'permissionManagement:position:delete',
- name: '删除',
- title: '删除',
- parentIdId: '1717148366037',
- dataPermission: false
- }
- ]
- }
- ]
- },
- {
- id: '1717148248870',
- code: 'userManagement',
- title: '用户管理',
- name: '用户管理',
- parentId: null,
- children: [
- {
- id: '1717148408202',
- parentId: '1717148248870',
- code: 'userAdmin',
- title: '用户',
- name: '用户',
- children: [
- {
- id: 'userAdmin:query',
- code: 'userAdmin:query',
- name: '查询',
- title: '查询',
- parentIdId: '1717148408202',
- dataPermission: true
- },
- {
- id: 'userAdmin:add',
- code: 'userAdmin:add',
- name: '新增',
- title: '新增',
- parentIdId: '1717148408202',
- dataPermission: false
- },
- {
- id: 'userAdmin:update',
- code: 'userAdmin:update',
- name: '修改',
- title: '修改',
- parentIdId: '1717148408202',
- dataPermission: false
- },
- {
- id: 'userAdmin:delete',
- code: 'userAdmin:delete',
- name: '删除',
- title: '删除',
- parentIdId: '1717148408202',
- dataPermission: false
- }
- ]
- }
- ]
- }
- ]
- };
- },
- methods: {
- /**
- * 复选框选中事件
- * 实现的效果:
- * 1、查询节点选中时,其相邻兄弟节点不变
- * 2、查询节点取消选中时,其相邻兄弟节点取消选中
- * 3、其相邻兄弟节点任何一个选中时,查询节点必选中
- * 注:查询节点 dataPermission:true
- * **/
- handleCheck(data, checked, indeterminate) {
- if (!data.children) {
- // 只处理叶子节点
- const parentNode = this.$refs.treeRef.getNode(data).parent;
- if (parentNode) {
- // 获取当前叶子节点的兄弟节点
- // const sublingsNode = this.getSiblingsById(this.treeData, data.id);
- // 获取当前叶子节点和兄弟节点
- const siblings = parentNode.data.children;
- const dataPermissionItem = siblings.find(
- (item) => item.dataPermission
- );
-
- if (data.dataPermission) {
- // 如果是查询节点,则取消选中所有非查询兄弟节点
- siblings.forEach((sibling) => {
- if (!sibling.dataPermission) {
- this.$refs.treeRef.setChecked(sibling, false, false);
- }
- });
- } else if (checked) {
- // 如果是非查询节点被选中,则确保查询节点也被选中
- this.$refs.treeRef.setChecked(dataPermissionItem, true, false);
- }
- }
- }
- }
-
- // /**
- // * 通过当前节点的 id 查找兄弟节点
- // * treeData:树形结构的数据源
- // * nodeId:当前节点的 id
- // * **/
- // getSiblingsById(treeData, nodeId) {
- // function findSiblings(nodes) {
- // for (const node of nodes) {
- // if (node.id === nodeId) {
- // return nodes.filter((item) => item.id !== nodeId);
- // }
- // if (node.children) {
- // const siblings = findSiblings(node.children, node.id);
- // if (siblings) return siblings;
- // }
- // }
- // return null;
- // }
-
- // return findSiblings(treeData, null);
- // }
- }
- };
- script>