el-table多级复选框全选与反选
问题描述
使用el-table结合tree结构和CheckBox实现二级复选框的全选与反选。
页面结构
<el-table
:data="dataList"
highlight-current-row
row-key="auditTypeId"
:expand-row-keys="expandKeys"
:tree-props="{ children: 'children', hasChildren: '!children.length' }"
>
<el-table-column width="50" type="index">
<template slot="header">
<el-checkbox v-model="allCheck" :indeterminate="indeterminate" @change="allCheckChange"></el-checkbox>
</template>
<template slot-scope="{ row }">
<el-checkbox
v-model="row.checked"
:indeterminate="row.indeterminate"
@change="changeItem($event, row)"
></el-checkbox>
</template>
</el-table-column>
<el-table-column prop="name" label="名称"></el-table-column>
</el-table>
选择逻辑
/**
* @Description: 全选反选
*/
allCheckChange(val) {
this.allCheck = val
this.indeterminate = false
const list = cloneDeep(this.dataList)
list.forEach(itemA => {
itemA.checked = val
itemA.indeterminate = false
itemA.children.forEach(itemB => {
itemB.checked = val
})
})
this.dataList = list
},
/**
* @Description: 单选一行
*/
changeItem(val, row) {
if (row.children) {
row.children.forEach(item => {
item.checked = val
})
} else {
const fItem = findItemByProp(this.dataList, 'auditTypeId', row.parentGuid)
const isChildAllCheck = fItem.children.every(item => {
return item.checked
})
const isOneCheck = fItem.children.some(item => {
return item.checked
})
const list = cloneDeep(this.dataList)
for (let i = 0; i < list.length; i++) {
const item = list[i]
if (item.auditTypeId === row.parentGuid) {
item.checked = isChildAllCheck
item.indeterminate = !isChildAllCheck
if (!val && !isOneCheck) {
item.indeterminate = false
}
break
}
}
this.dataList = list
}
this.allCheck = this.dataList.every(item => {
return item.checked
})
if (this.allCheck) {
this.indeterminate = false
} else {
this.indeterminate = this.getCheckedData().length > 0
}
},
/**
* @Description: 获取选择的数据
* @param {*}
* @return {*}
*/
getCheckedData() {
const arr = []
this.dataList.forEach(itemA => {
itemA.children.forEach(itemB => {
if (itemB.checked) {
arr.push(itemB)
}
})
})
return arr
},
/**
* @Description: 递归遍历树初始化数据(返显数据)
* @param {*} data
* @return {*}
*/
recursiveProcess(data) {
const vm = this
vm.selMap.clear()
this.expandKeys = []
let ids = []
if (this.curOptions.select.length) {
const ops = this.curOptions.options
ids = getPropFromArr(ops, 'val')
}
const set = new Set()
const initData = list => {
list.forEach(item => {
item.checked = false
item.indeterminate = false
if (ids.includes(item.auditTypeId)) {
item.checked = true
// 只保留子级选择的数据
const fItem = findItemByProp(data, 'auditTypeId', item.parentGuid)
set.add(fItem.auditTypeId)
vm.selMap.set(fItem.auditTypeId, item)
}
if (item.children) {
initData(item.children)
}
})
this.expandKeys = [...set]
}
initData(data)
},