系统管理 - 角色管理 - 新建/修改
1. 问题复原:
在新建一个角色的时候,如上图设置授权,那么等你修改的时候回显数据就会如下:
2. 代码解析
this.$http({
url: this.$http.adornUrl(`/sys/role/info/${this.dataForm.id}`),
method: 'get',
params: this.$http.adornParams()
}).then(({data}) => {
if (data && data.code === 0) {
...
//tempKey: -666666
// 临时key, 用于解决tree半选中状态项不能传给后台接口问题. # 待优化
//作者在data中定义了tempKey,并标注了说明,说明作者知道这个问题。
//但是经测试没发现这个变量有实际作用
//原代码开始
var idx = data.role.menuIdList.indexOf(this.tempKey)
if (idx !== -1) {
data.role.menuIdList.splice(idx, data.role.menuIdList.length - idx)
}
//下面代码将回显数据一次性赋值给el-tree处理,导致当el判断父节点已经选中的时候
//就会把所有子节点都选中,问题就出现在这里
this.$refs.menuListTree.setCheckedKeys(data.role.menuIdList)
//原代码结束
//解决方案代码
//只需要把把一次性的赋值,让每个节点单独去处理,这样就不会出现全选的bug
//(单个设置相当于自己点击,el-tree会自行判断是否需要全选/半选)
data.role.menuIdList.forEach(item => this.$refs.menuListTree.setChecked(item, true))
}
})
3. 总结
- 因为项目选中子节点,就应该选中父节点,如果子节点没有全选,回显默认应该是半选状态,而问题恰恰出现在这个半选状态,当时作者应该是没想好如何解决这个半选方案。
- 而后在作者的新项目中查看代码发现已经解决这个问题,通过单个设置的方式处理,并在提交给后台form数据时将选中和半选中的节点合并提交,这样就完美解决这个问题。
this.dataForm.menuIdList = [
...this.$refs.menuListTree.getHalfCheckedKeys(),
...this.$refs.menuListTree.getCheckedKeys()
]