适合按钮级别权限的el-tree

421 阅读2分钟

很多使用Element-UI的后台系统都有权限控制系统,当权限要求控制到按钮级别时,我们可以将el-tree的check-stricty设置为true。 check-stricty:在显示复选框的情况下,是否严格的遵循父子不互相关联的做法 ,默认为false。这样,即便页面下的按钮全不勾选,页面也是可以被勾选上的。

然而新的问题又来了:太麻烦了。你需要手动一个个去勾选。所以我改造了el-tree的源码,做到了如下的效果:

chrome-capture-2023-5-18.gif

先整理下思路:

  1. 默认是check-stricty:true模式,不关联。
  2. 选中节点时,能将上层节点、子节点都选中(check-stricty:false)
  3. 取消的是按钮时候,仅仅取消按钮节点本身(check-stricty:true)
  4. 取消的是除了按钮类型之外的节点时,取消子节点。同时取消父节点,如果兄弟节点没有被选中的话(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,都通过上面的函数去获取。 到此上面的基本功能已经实现了。

今天太晚了,有空就把代码上去。 如果有帮助请给我点个赞,谢谢。