一、效果图(全选、经办、授权)

对应代码

<template>
  <div style="width: 360px;">
    <el-tree
      :data="prdList"
      show-checkbox
      node-key="id"
      default-expand-all
      :expand-on-click-node="false">
      <div class="tree-node" slot-scope="{ node, data }">
        <span>{{ node.label }}</span>
        <span v-if="!node.isLeaf">
          <el-checkbox :indeterminate="data.isIndeterminate" v-model="data.checkedFlag" @change="checkAllChange(node, data.checkedFlag)">全选</el-checkbox>
        </span>
        <span v-else>
          <el-checkbox v-model="data.athrFlag" true-label="1" false-label="0" @change="clickNode(node, data)">经办</el-checkbox>
          <el-checkbox v-model="data.landFlag" true-label="1" false-label="0" @change="clickNode(node, data)">授权</el-checkbox>
        </span>
      </div>
    </el-tree>
  </div>
</template>
<script>
  export default {
    data() {
      return {
        prdList: [{
          id: 1,
          label: '一级 1',
          children: [{
            id: 4,
            label: '二级 1-1',
            children: [{
              id: 9,
              label: '三级 1-1-1'
            }, {
              id: 10,
              label: '三级 1-1-2',
              children: [
                { id: 22, label: '四级 1-1-1' },
                { id: 23, label: '四级 1-1-2' },
                { id: 24, label: '四级 1-1-3' },
              ]
            }]
          },
          {
            id: 14,
            label: '二级 1-2',
            children: [{
              id: 19,
              label: '三级 1-2-1'
            }, {
              id: 110,
              label: '三级 1-2-2'
            }]
          }]
        }, {
          id: 2,
          label: '一级 2',
          children: [{
            id: 5,
            label: '二级 2-1'
          }, {
            id: 6,
            label: '二级 2-2'
          }]
        }, {
          id: 3,
          label: '一级 3',
          children: [{
            id: 7,
            label: '二级 3-1'
          }, {
            id: 8,
            label: '二级 3-2'
          }]
        }],
        defaultProps: {
          children: 'children',
          label: 'label'
        }
      }
    },
    created() {
      this.init()
    },
    methods: {
      traversalNode(list, callback) {
        if (!list && !Array.isArray(list)) {
          throw new Error('required an Array.')
        }
        for (const item of list) {
          let children = item.children;
          if (children && children.length > 0) {
            this.traversalNode(children, callback)
          }
          const isBreak = callback(item)
          if (isBreak) {
            break;
          }
        }
      },
      init() {
        this.traversalNode(this.prdList, (item) => {
          this.$set(item, 'athrFlag', '0')
          this.$set(item, "landFlag", '0')
          this.$set(item, 'isIndeterminate', false)
          this.$set(item, 'checkedFlag', false)
        })
      },
      checkAllChange(node, value) {
        this.traversalSon(node, value)
        if(node.parent) {
          this.traversalParent(node.parent)
        }
      },
      traversalSon(node, value) {
        node.childNodes.forEach((item) => {
          if(item.isLeaf) {
            item.data.athrFlag = value ? '1' : '0'
            item.data.landFlag = value ? '1' : '0'
          } else {
            item.data.checkedFlag = value
            item.data.isIndeterminate = false
            this.traversalSon(item, value)
          }
        })
      },
      traversalParent(node) {
        let allCount = 0 // 当前节点下 所有子节点 总数
        let checkedCount = 0 // 当前节点的所有子节点 已选个数
        let isIndeterminate = false
        node.childNodes.forEach((item) => {
          if(item.isLeaf) {
            allCount += 2 // 用两个复选框(经办 授权)
            // 经办
            if(item.data.athrFlag === '1') {
              checkedCount++
            }
            // 授权
            if(item.data.landFlag === '1') {
              checkedCount++
            }
          } else {
            allCount++
            if(item.data.checkedFlag === false && item.data.isIndeterminate === true) {
              isIndeterminate = true
            }
            if(item.data.checkedFlag) {
              checkedCount++
            }
          }
        })
        // 设置 当前节点 选中、半选、未选状态
        this.$set(node.data, 'checkedFlag', checkedCount === allCount && allCount !== 0)
        this.$set(node.data, 'isIndeterminate', isIndeterminate ? true : checkedCount > 0 && checkedCount < allCount)

        if(node.parent) {
          this.traversalParent(node.parent)
        }      
      },
      clickNode(node) {
        this.traversalParent(node.parent)
      }
    }
  };
</script>
<style scoped>
.tree-node{
  flex: 1;
  display: flex;
  align-content: center;
  justify-content: space-between;
  padding-right: 10px;

}
</style>

二、效果图(经办、授权)

对应代码

<template>
  <div style="width: 360px;">
    <el-tree
      :data="prdList"
      show-checkbox
      node-key="id"
      default-expand-all
      :expand-on-click-node="false">
      <div class="tree-node" slot-scope="{ node, data }">
        <span>{{ node.label }}</span>
        <span v-if="!node.isLeaf">
          <el-checkbox :indeterminate="data.athrIndeterminate" v-model="data.athrFlag" @change="checkAllChange(node, data.athrFlag, 'athrFlag', 'athrIndeterminate')">经办</el-checkbox>
          <el-checkbox :indeterminate="data.landIndeterminate" v-model="data.landFlag" @change="checkAllChange(node, data.landFlag, 'landFlag', 'landIndeterminate')">授权</el-checkbox>
        </span>
        <span v-else>
          <el-checkbox v-model="data.athrFlag" @change="clickNode(node, 'athrFlag', 'athrIndeterminate')">经办</el-checkbox>
          <el-checkbox v-model="data.landFlag" @change="clickNode(node, 'landFlag', 'landIndeterminate')">授权</el-checkbox>
        </span>
      </div>
    </el-tree>
  </div>
</template>
<script>
  export default {
    data() {
      return {
        prdList: [{
          id: 1,
          label: '一级 1',
          children: [{
            id: 4,
            label: '二级 1-1',
            children: [{
              id: 9,
              label: '三级 1-1-1'
            }, {
              id: 10,
              label: '三级 1-1-2',
              children: [
                { id: 22, label: '四级 1-1-1' },
                { id: 23, label: '四级 1-1-2' },
                { id: 24, label: '四级 1-1-3' },
              ]
            }]
          },
          {
            id: 14,
            label: '二级 1-2',
            children: [{
              id: 19,
              label: '三级 1-2-1'
            }, {
              id: 110,
              label: '三级 1-2-2'
            }]
          }]
        }, {
          id: 2,
          label: '一级 2',
          children: [{
            id: 5,
            label: '二级 2-1'
          }, {
            id: 6,
            label: '二级 2-2'
          }]
        }, {
          id: 3,
          label: '一级 3',
          children: [{
            id: 7,
            label: '二级 3-1'
          }, {
            id: 8,
            label: '二级 3-2'
          }]
        }],
        defaultProps: {
          children: 'children',
          label: 'label'
        }
      }
    },
    created() {
      this.init()
    },
    methods: {
      traversalNode(list, callback) {
        if (!list && !Array.isArray(list)) {
          throw new Error('required an Array.')
        }
        for (const item of list) {
          let children = item.children;
          if (children && children.length > 0) {
            this.traversalNode(children, callback)
          }
          const isBreak = callback(item)
          if (isBreak) {
            break;
          }
        }
      },
      init() {
        this.traversalNode(this.prdList, (item) => {
          this.$set(item, 'athrFlag', false)
          this.$set(item, "landFlag", false)
          this.$set(item, 'athrIndeterminate', false)
          this.$set(item, 'landIndeterminate', false)
        })
      },
      checkAllChange(node, value, flag, indeterminate) {
        this.traversalSon(node, value, flag, indeterminate)
        this.updateTreeUp(node, flag, indeterminate)
      },
      traversalSon(node, value, flag, indeterminate) {
        node.childNodes.forEach((item) => {
          if(item.isLeaf) {
            item.data[flag] = value ? true : false
          } else {
            item.data[flag] = value
            item.data[indeterminate] = false
            this.traversalSon(item, value, flag, indeterminate)
          }
        })
        node.data[indeterminate] = false
      },
      clickNode(node, flag, indeterminate) {
        this.updateTreeUp(node, flag, indeterminate)
      },
      updateTreeUp(node, flag, indeterminate) {
        let parent = node.parent
        if(!parent) return false
        if(node.data[flag] == true) {
          this.$set(parent.data, flag, parent.childNodes.every(node => node.data[flag] ));
          this.$set(parent.data, indeterminate, !parent.data[flag]);
        } else {
          this.$set(parent.data, flag, false);
          this.$set(parent.data, indeterminate, parent.childNodes.some(node => node.data[flag] || node.data[indeterminate]));
        }

        this.updateTreeUp(parent, flag, indeterminate)
      }
    }
  };
</script>
<style scoped>
.tree-node{
  flex: 1;
  display: flex;
  align-content: center;
  justify-content: space-between;
  padding-right: 10px;

}
</style>

Wei1
44 声望3 粉丝

关注MP【前端学馆】程序员IT编程书籍分享!