场景
element 树状表格,表格全选时所有项(包括所有子节点)都选中,选中树状表格父节点时,这个父节点下所有子节点也都要选中,如果某个父节点下的所有子节点没有全部,则这个父节点处于半选状态
效果图
实现
通过row-class-name和header-row-class-name控制复选框不确定状态显示,通过select-all和select事件判断是否选中,isSelect字段代表是否选中,true是选中,false是不选中,空为不确定
qz-pro-table组件是根据el-table进行二次封装,使用与el-table一样
<template>
<qz-pro-table
ref="table"
border
row-key="id"
:data-source="getDataList"
@select-all="selectAllFun"
:row-class-name="rowClassNameFun"
:header-row-class-name="headerRowClassName"
@select="selectFun"
:tree-props="{
children: 'databaseSourceList',
hasChildren: 'hasChildren',
}"
>
<qz-table-column type="selection" width="45"></qz-table-column>
<qz-table-column
prop="name"
label="任务名称"
min-width="100"
show-overflow-tooltip
></qz-table-column>
<qz-table-column
prop="successTime"
label="最近成功时间"
min-width="150"
show-overflow-tooltip
>
<template slot-scope="{ row }">{{
row.successTime || "--" | timeFormat("YYYY-MM-DD HH:mm:ss")
}}</template>
</qz-table-column>
</qz-pro-table>
</template>
<script>
export default {
data() {
return {
listParams: {
page: 1,
size: 10,
},
renderDynamic: [],
};
},
methods:{
getDataList(params) {
this.listParams.page = params.page;
this.listParams.size = params.limit;
return scanService
.getTaskList(this.filterObj, this.listParams).then((res) => {
this.renderDynamic = res.data.rows;
return res;
});
},
// 判断是不是全选
checkIsAllSelect() {
this.oneProductIsSelect = [];
this.renderDynamic.forEach((item) => {
this.oneProductIsSelect.push(item.isSelect);
});
//判断一级产品是否是全选.如果一级产品全为true,则设置为取消全选,否则全选
let isAllSelect = this.oneProductIsSelect.every((selectStatusItem) => {
return true == selectStatusItem;
});
return isAllSelect;
},
// 全选或者全不选
selectAllFun(selection) {
let isAllSelect = this.checkIsAllSelect();
this.renderDynamic.forEach((item) => {
item.isSelect = isAllSelect;
this.$refs.table.$refs.table.toggleRowSelection(item, !isAllSelect);
this.selectFun(selection, item);
});
},
selectFun(selection, row) {
this.setRowIsSelect(row);
},
setRowIsSelect(row) {
//当点击父级点复选框时,当前的状态可能为未知状态,所以当前行状态设为false并选中,即可实现子级点全选效果
if (row.isSelect === "") {
row.isSelect = false;
this.$refs.table.$refs.table.toggleRowSelection(row, true);
}
row.isSelect = !row.isSelect;
//判断操作的是子级点复选框还是父级点复选框,如果是父级点,则控制子级点的全选和不全选
if (row.databaseSourceList && row.databaseSourceList.length > 0) {
row.databaseSourceList.forEach((item) => {
item.isSelect = row.isSelect;
this.$refs.table.$refs.table.toggleRowSelection(item, row.isSelect);
});
} else {
//操作的是子节点 1、获取父节点 2、判断子节点选中个数,如果全部选中则父节点设为选中状态,如果都不选中,则为不选中状态,如果部分选择,则设为不明确状态
let parentId = row.taskId;
this.renderDynamic.forEach((item) => {
let isAllSelect = [];
if (item.id == parentId) {
item.databaseSourceList.forEach((databaseSourceListItem) => {
isAllSelect.push(databaseSourceListItem.isSelect);
});
if (
isAllSelect.every((selectItem) => {
return true == selectItem;
})
) {
item.isSelect = true;
this.$refs.table.$refs.table.toggleRowSelection(item, true);
} else if (
isAllSelect.every((selectItem) => {
return false == selectItem;
})
) {
item.isSelect = false;
this.$refs.table.$refs.table.toggleRowSelection(item, false);
} else {
item.isSelect = "";
}
}
});
}
},
// 每行多选框不确定选择
rowClassNameFun({ row }) {
if (row.isSelect === "") {
return "indeterminate";
}
},
// 表头多选框不确定选择
headerRowClassName({ row }) {
let oneProductIsSelect = [];
this.renderDynamic.forEach((item) => {
oneProductIsSelect.push(item.isSelect);
});
if (
oneProductIsSelect.includes("") ||
(oneProductIsSelect.includes(true) &&
oneProductIsSelect.includes(false))
) {
return "indeterminate";
}
return "";
},
}
}
</script>
<style lang="less" scoped>
/deep/.indeterminate {
.el-table-column--selection .cell .el-checkbox {
display: block !important;
}
.el-checkbox__input .el-checkbox__inner {
background-color: #4a97eb !important;
border-color: #4a97eb !important;
color: #fff !important;
}
}
/deep/.indeterminate .el-checkbox__input.is-checked .el-checkbox__inner::after {
transform: scale(0.5);
}
/deep/.indeterminate .el-checkbox__input .el-checkbox__inner::after {
border-color: #c0c4cc !important;
background-color: #c0c4cc;
}
/deep/.indeterminate .el-checkbox__input .el-checkbox__inner::after {
content: "";
position: absolute;
display: block;
background-color: #fff;
height: 2px;
transform: scale(0.5);
left: 0;
right: 0;
top: 5px;
width: auto !important;
}
</style>
版权声明:本文为meimeib原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。