The element tree control (tree) realizes the association between the parent and the child, and the child is not associated with the parent; manually set the half-selected state

The element tree control (tree) realizes the association between the parent and the child, and the child is not associated with the parent; manually set the half-selected state

First, the code for the tree component

<el-tree
     ref="tree" 
     :data="list" 
     node-key="name" 
     show-checkbox 
     :props="defaultProps" 
     highlight-current 
     check-strictly 
     @check="handCheck" 
     @check-change="checkChange" 
     :default-checked-keys="checkedKeys" />

Focus on the method used
insert image description here

insert image description here
The check-strictly field must be set to true so that the parent and child nodes are not associated with each other. In this way, we can do the operation of node association or not by ourselves.

Then, the code to implement the function

There are three levels of tree nodes: 1. Menu parent node permissions; 2. Menu permissions; 3. Button permissions

Checked state displayed by default

getPermissions(_this.ur, _this.roleName)
        .then((result) => {
    
    
         let _this = this
         _this.list = result.groups;
          const tree = [];
          _this.list.forEach((listItem) => {
    
    
          //因为子节点最内层的子节点比较好操作,省去了一段代码
         //..............................
         //子节点添加勾选状态
          tree.push(listItem);
          })
          _this.$nextTick(() => {
    
    
            _this.$refs.tree.setCheckedNodes(_this.pertemp);
          });
          // console.log(tree);

          // 设置父级节点的勾选状态
          let checkChild = []
          tree.forEach(item => {
    
    
            // 如果有子级并且只要有一个子级的isGranted为true
            if (item.children && item.children.some(ele => ele.isGranted)) {
    
    
              // 就默认设置最外层父节点为勾选状态。筛选isGranted为true的二级节点也设置为勾选状态
              checkChild.push(item.name, item.children.filter(child => child.isGranted).map(child => {
    
     return child.name }))
            }
          });
          _this.$nextTick(() => {
    
    
            _this.checkedKeys = checkChild.flat()
            setTimeout(() => {
    
    
              // 父级节点
              tree && tree.length > 0 && setIndeterminate(tree, 'tree')

              function setIndeterminate (node, treeName) {
    
    
                node.forEach(item => {
    
    
                  let treeNode = _this.$refs[treeName].getNode(item);
                  // 如果子节点未全部选中,则设置父节点为半选状态
                  if (treeNode.childNodes.map(ele => ele.checked ).some(ele => !ele)) {
    
    
                    treeNode.indeterminate = true
                  }
                  // 如果子节点全部未选中取消父节点的半选中状态
                  if (treeNode.childNodes.every(ele => !ele.checked)) {
    
    
                    // treeNode.checked = false
                    treeNode.indeterminate = false
                  }
                  // 如果是二级节点,子节点全不选但是当前节点是勾选状态的时候,默认设置变为半选状态
                  if (treeNode.level == 2 && treeNode.checked && treeNode.childNodes.every(ele => !ele.checked)) {
    
    
                    treeNode.indeterminate = true
                  }
                  // console.log(treeNode);
                  // 子节点递归
                  item.children && item.children.length > 0 && setIndeterminate(item.children, 'tree')
                });
              }
            }, 500);
          })
        })
        .catch((err) => {
    
    
          console.log(err);
        });

The operation of checking the state when clicking the node

// 覆盖原有勾选功能,父与子关联,子与父不关联
    handCheck (data, node) {
    
    
      this.hanleCheck(data, node, 'tree')
    },
    hanleCheck (data, node, treeName) {
    
    
      // console.log(data, node);
      const _this = this
      // 获取当前节点是否被选中
      const isChecked = _this.$refs[treeName].getNode(data).checked
      // 如果当前节点被选中,则遍历下级子节点并选中,如果当前节点取消选中,则遍历下级节点并取消
      if (isChecked) {
    
    
        // 判断该节点是否有下级节点,如果有那么遍历设置下级节点为选中
        data.children && data.children.length > 0 && setChildreChecked(data.children, true)
      } else {
    
    
        // 如果节点取消选中,则取消该节点下的子节点选中
        data.children && data.children.length > 0 && setChildreChecked(data.children, false)
      }
      function setChildreChecked (node, isChecked) {
    
    
        node.forEach(item => {
    
    
          item.children && item.children.length > 0 && setChildreChecked(item.children, isChecked)
          // 修改勾选状态
          _this.$refs[treeName].setChecked(item.name, isChecked)
        })
      }
    },
    checkChange (data, checked, indeterminate) {
    
    
      let _this = this;
      // console.log(data, checked, indeterminate);
      // 选中全部子节点,父节点也默认选中,但是子节点再次取消勾选或者全部子节点取消勾选也不会影响父节点勾选状态
      let checkNode = _this.$refs.tree.getNode(data)//获取当前节点
      // 勾选部分子节点,父节点变为半选状态
      if (checkNode.parent && checkNode.parent.childNodes.some(ele => ele.checked)) {
    
    
        checkNode.parent.indeterminate = true
      }
      // 勾选全部子节点,父节点变为全选状态
      if (checkNode.parent && checkNode.parent.childNodes.every(ele => ele.checked)) {
    
    
        checkNode.parent.checked = true
        checkNode.parent.indeterminate = false
      }
      // 如果取消所有第二节点的勾选状态,则第一层父节点也取消勾选
      if (checkNode.level == 2 && checkNode.parent.childNodes.every(ele => !ele.checked)) {
    
    
        checkNode.parent.checked = false
        checkNode.parent.indeterminate = false
      }
    },

Guess you like

Origin blog.csdn.net/yangsi0706/article/details/125225743