前言
前几天写项目时候遇到一个数据回显的小问题,当时解决后忘记记录了,今天来码一码
el-tree的结构
<el-tree
style="margin: 20px 0"
ref="tree"
:data="allMenuList"
node-key="id"
show-checkbox
default-expand-all
:props="defaultProps"
/>
data - 展示数据(原始的列表)node-key - 唯一标识default-expand-all - 是否默认展开所有节点show-checkbox - 节点是否可被选择
lazy - 是否懒加载子节点,需与 load 方法结合使用current-node-key - 当前选中的结点
当然在获取原始列表之后,我们还需要根据当前所选中的 id 来查询其所有的idList
最终通过idList进行数据回显
this.$refs.tree.setCheckedKeys(this.idList)
注意 : 这里的idList封装或不封装成树形结构都是ok的
问题定位
然而完成上述配置后,并没有正确回显所有数据,父节点以下的内容会全部被选中🙃

图中可以看到全选和半选的区别,当我们选中parent-node时,其下所有的子节点都会被选中!! 由于在数据库中存储的数据是按层级存储的 例如 parent-id -> sub-parent-id -> node-id
所以说 存储的子节点必有其父节点存在,所以所有数据都会被选中
解决方案
根据上述分析我们只需要删除父节点,转而保留所有的子节点即可
public Result getAssignByRoleId(@PathVariable("id") Long id){
//获取给该角色分配的idList
List<Long> idList = sysRoleMenuService.getAssign(id);
//通过idList获取到完整的菜单列表
LambdaQueryWrapper<SysMenu> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.in(SysMenu::getId,idList).eq(SysMenu::getStatus,1);
List<SysMenu> roleMenuList = sysMenuService.list(lambdaQueryWrapper);
//获取树形结构,这部很重要
List<SysMenu> node = sysMenuService.getNode(roleMenuList);
//去除父节点
List<Long> subList = getSubIdList(node,new ArrayList<Long>());
return Result.success(subList);
}
//递归去除父结点
private List<Long> getSubIdList(List<SysMenu> roleMenuList,List<Long> subList) {
for(SysMenu sysMenu : roleMenuList){
if(sysMenu.isSelect())//判断是否已经处理过
continue;
List<SysMenu> children = sysMenu.getChildren();
if(CollectionUtils.isEmpty(children)) {//只留最里的节点
subList.add(sysMenu.getId());
sysMenu.setSelect(true);
}
else
subList = getSubIdList(children,subList); //有孩子就一直递归到没有孩子
}
return subList;
}
下面是Menu类中定义的两个属性 - 方便形成树形结构

1933






