效果图
不废话上代码
<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>