很多使用Element-UI的后台系统都有权限控制系统,当权限要求控制到按钮级别时,我们可以将el-tree的check-stricty设置为true。
check-stricty:在显示复选框的情况下,是否严格的遵循父子不互相关联的做法 ,默认为false。
这样,即便页面下的按钮全不勾选,页面也是可以被勾选上的。
然而新的问题又来了:太麻烦了。你需要手动一个个去勾选。所以我改造了el-tree的源码,做到了如下的效果:
先整理下思路:
- 默认是check-stricty:true模式,不关联。
- 选中节点时,能将上层节点、子节点都选中(check-stricty:false)
- 取消的是按钮时候,仅仅取消按钮节点本身(check-stricty:true)
- 取消的是除了按钮类型之外的节点时,取消子节点。同时取消父节点,如果兄弟节点没有被选中的话(check-stricty:false)。
树的行为和我们当前点击的节点是有关系的,所以点击时候要将节点信息保存起来。
再啰嗦几句el-tree的结构
TreeStore > node
TreeStore的root就是node根节点。
node根据data深度遍历创建node,挂载在childNodes属性上。TreeStore传递给node配置属性,node在TreeStore.nodesMap上注册。
tree > tree-node
tree-node组件v-model了node,node的checked属性设置为true,tree-node就选上了。
node实现了节点的基本功能,TreeStore主要将树的逻辑功能实现。
当点击tree-node的CheckBox时,触发了handleCheckChange:
原先:this.node.setChecked(ev.target.checked, !this.tree.checkStrictly)
=====》修改为
const nodeData = this.node.data || {}
this.tree.store.setCustomClickData({ ...nodeData, isChecked: ev.target.checked })
const status = this.tree.store.getCheckStrictly()
this.node.setChecked(ev.target.checked, !status)
checkStrictly之前是直接从配置的属性中读取的,现在写了个函数:
class TreeStore {
...
getCheckStrictly() {
// 初始是true,不关联
if (!this.customClickData) return true
// 取消了按钮,是true,不关联
if (this.customClickData?.type === '按钮类型' && this.customClickData?.isChecked === false) {
return true
}
return false
}
}
此外node.js中的setChecked、reInitChecked函数中的check-stricty,都通过上面的函数去获取。 到此上面的基本功能已经实现了。
今天太晚了,有空就把代码上去。 如果有帮助请给我点个赞,谢谢。