element-ui el-tree实现权限配置

element-ui el-tree实现权限配置_第1张图片
element文档
核心代码块

      
            
            
            
                取 消
                确 定
              
        
  data() {
     
            return {
     
                visible: false,
                menuList: [],
                defaultProps: {
     
                    children: 'children',
                    label: 'name'
                },
                checkedKeys: [], // 已配置的菜单
                checkedMenuIds: [],
                roleId: "",
                boolChecked: false, // 用于判断是否点过菜单选项,确认是否调用过check方法
            }
        },

第一步 获取树形结构menuList,根据自己字段配置defaultProps, node-key
第二步 配置默认选中,即checkedKeys,
问题:若选中项有(系统管理,角色管理,菜单管理)这个数组,父节点选中,则子节点会全部选中,就会出现用户管理也被选中了(意思就是在设置默认选中的时候只设置叶子节点)
解决:后端封装数据,若父节点有子节点,把子节点挂在父节点上。返回的List不是树形结构,但是List里每个节点都是树形结构。前端只需要把List里的每个元素的叶子节点放进checkedKeys就好了。 我之前已经写好了方法,直接调用就好,主要是方便,可根据自己需要调整。( 代码里需要的类和方法放在了最后)

 // 这里返回的不是树形结果,只是把父节点的子节点set进去 原因 element-ui el-tree 在setCheckedKeys会把所有子节点都选中
    @Override
    public List<MenuVo> getRoleMenuList(Long roleId) {
     
        List<MenuVo> menuList = menuMapper.getRoleMenuList(roleId);
        if (menuList == null || menuList.size() == 0) {
     
            return null;
        }
        // 构建children
        List<MenuVo> menuVoList = new ArrayList<>();
        // 先找到所有的一级菜单
        for (MenuVo menu : menuList) {
     
            // 一级菜单没有parentId
            if (menu.getParentId() == null || menu.getParentId() == 0) {
     
                menuVoList.add(menu);
            }
        }
        // 为一级菜单设置子菜单,getChild是递归调用的
        for (MenuVo menu : menuVoList) {
     
            menu.setChildren(getChild(menu.getId(), menuList));
        }
        // 注意这里返回menuList,而不是menuVoList
        return menuList;
    }
  let list = res.data;
  if(list) {
     
	  list.forEach(item => {
     
	      if (item.children === null) {
     
	          this.checkedKeys.push(item.id);
	      }
	  })
  }
  this.$refs.tree.setCheckedKeys(this.checkedKeys);

第三步 保存选项,我的实现方式如下, 使用@check=“check”
把所有选中的选项id 传个后端来处理,后端根据角色已有的菜单,判断出哪些是新增的菜单,哪些是删除的菜单

    check(menuData, checkedData) {
     
                this.boolChecked = true;
                this.checkedMenuIds = checkedData.checkedKeys.concat(checkedData.halfCheckedKeys);
   },
   saveRoleMenu() {
     
                if (!this.boolChecked) {
     
                    this.visible = false;
                    return;
                }
                let param = {
     
                    menuIds: this.checkedMenuIds.join(","),
                    roleId: this.roleId
                }
                this.$api.sys.saveRoleMenu(param).then(res => {
     
                    if (res.code === 0) {
     
                        this.$message({
     
                            type: "success",
                            message: "保存成功!"
                        });
                        this.roleId = "";
                        this.checkedMenuIds = [];
                        this.visible = false;
                    } else {
     
                        this.$message.error({
     
                            message: res.message
                        });
                    }
                });
            }
  @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveRoleMenu(List<Long> menuIds, Long roleId, Long userId) {
     
        // 原有的菜单列表
        List<MenuVo> list = menuMapper.getRoleMenuList(roleId);
        // 原有的菜单
        List<Long> menuArr = new ArrayList<>();
        // 新增的菜单
        List<SysRoleMenu> addRoleMenuList = new ArrayList<>();
        SysRoleMenu roleMenu;
        // 删除的菜单
        List<Long> removeArr = new ArrayList<>();
        for (MenuVo menu : list) {
     
            menuArr.add(menu.getId());
        }
        for (Long menuId : menuIds) {
     
            if (!menuArr.contains(menuId)) {
     
                roleMenu = new SysRoleMenu();
                roleMenu.setCreateUser(userId);
                roleMenu.setMenuId(menuId);
                roleMenu.setRoleId(roleId);
                addRoleMenuList.add(roleMenu);
            }
        }
        for (Long menuId : menuArr) {
     
            if (!menuIds.contains(menuId)) {
     
                removeArr.add(menuId);
            }
        }
        try {
     
            if(removeArr.size() > 0) {
     
                roleMenuMapper.deleteBatchRoleMenu(removeArr, roleId, userId);
            }
            if (addRoleMenuList.size() > 0) {
     
                roleMenuMapper.batchInsert(addRoleMenuList);
            }
            return true;
        } catch (Exception e) {
     
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            logger.error("角色授权失败", e);
            return false;
        }
    }
@Data
public class MenuVo {
     
    private Long id;
    private Long parentId;
    private String name;
    private String url;
    private String icon;
    private Integer level;
    private List<MenuVo> children;
}


    private List<MenuVo> getChild(Long menuId, List<MenuVo> rootMenu) {
     
        // 子菜单
        List<MenuVo> childList = new ArrayList<>();
        for (MenuVo menuVo : rootMenu) {
     
            // 遍历所有节点,将父菜单id与传过来的id比较
            if (menuVo.getParentId() != null) {
     
                if (menuVo.getParentId().equals(menuId)) {
     
                    childList.add(menuVo);
                }
            }
        }
        // 把子菜单的子菜单再循环一遍
        for (MenuVo menuVo : childList) {
     // 没有url子菜单还有子菜单
            // 递归
            menuVo.setChildren(getChild(menuVo.getId(), rootMenu));
        } // 递归退出条件
        if (childList.size() == 0) {
     
            return null;
        }
        return childList;
    }

你可能感兴趣的:(vue,java,vue)