需求: Tree 树形控件需要实现父子不关联勾选,但同时也要实现全选、反选、半选功能 由于按照官网设置check-strictly后,最顶级“全部”也属于父级导致选中全部但未实现全选等功能,又想父子不关联又想全选,那就需要手动写逻辑啦
效果:
解决:单独把全部抽离出来,拉平树结构数据,根据选中长度同拉平后的数据长度进行对比实现全选、反选、半选
上代码:
<template>
<div>
<el-checkbox v-model="checkecd" :indeterminate="indeterminate" @change="checkedAll">
全部
</el-checkbox>
<el-tree ref="tree" :data="treeData" show-checkbox node-key="id" check-strictly @check-change="checkChange">
</el-tree>
</div>
</template>
<script>
export default {
data() {
return {
treeData: [
{
id: 1,
label: '一级 1',
children: [
{
id: 4,
label: '二级 1-1',
children: [
{
id: 9,
label: '三级 1-1-1'
},
{
id: 10,
label: '三级 1-1-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'
}
]
}
], // 树形数据
levelData: [], // 拉平后的treeData
checkecd: false,// 全选状态
indeterminate: false // 半选状态
}
},
created() {
this.getLevelData()
},
methods: {
// 获取拉平后的数据
getLevelData() {
let cloneData = JSON.parse(JSON.stringify(this.treeData))
this.levelData = this.recursion(cloneData)
},
// 全选、反选
checkedAll() {
if (this.checkecd) {
this.$refs.tree.setCheckedNodes(this.levelData)
} else {
this.$refs.tree.setCheckedNodes([])
}
},
// 树结构勾选
checkChange(item, isChecked) {
// 获取勾选的数据
let checkNode = this.$refs.tree.getCheckedKeys()
// 如果勾选数量===拉平后的treeData的数量 那么相当于全选 反之则是反选
// 如果小于数组数量则是半选
if (checkNode.length === this.levelData.length) {
this.checkecd = true
this.indeterminate = false
} else if (checkNode.length === 0) {
this.checkecd = false
this.indeterminate = false
} else if (checkNode.length < this.levelData.length) {
this.indeterminate = true
}
},
// 递归调用
recursion(arr) {
return [].concat(...arr.map(item => {
if (item.children) {
let arr = [].concat(item, ...this.recursion(item.children))
delete item.children
return arr
}
return [].concat(item)
}
))
}
}
}
</script>