目标需求:
- 父节点禁止勾选,只能勾选最末级子节点
- 支持切换单个最末级子节点
- 全选或取消全选所有最末级节点
<template>
<div>
<el-table
ref="table"
:data="tableData"
row-key="id"
border
:indent="10"
:select-on-indeterminate="true"
@select="select"
@select-all="selectAll"
@selection-change="selectionChange"
default-expand-all
:tree-props="{ children: 'children' }"
>
<el-table-column
type="selection"
width="50"
align="center"
:selectable="selectable"
>
<template v-slot="scope">
<!---自定义勾选列-从调试工具复制一份模板->
<div class="cell">
<label
:class="{
'el-checkbox': true,
'is-checked': scope.row.isRowChecked,
'is-disabled':
Array.isArray(scope.row.children) &&
scope.row.children.length > 0
}"
>
<span
:class="{
'el-checkbox__input': true,
'is-checked': scope.row.isRowChecked,
'is-disabled':
Array.isArray(scope.row.children) &&
scope.row.children.length > 0
}"
>
<span class="el-checkbox__inner"> </span>
<input
v-if="
Array.isArray(scope.row.children) &&
scope.row.children.length > 0
"
type="checkbox"
aria-hidden="false"
disabled
class="el-checkbox__original"
value=""
/>
<input
v-else
type="checkbox"
aria-hidden="false"
class="el-checkbox__original"
value=""
@change="clickChildren(scope.row)"
/>
</span>
</label>
</div>
</template>
</el-table-column>
<el-table-column prop="name" label="姓名" sortable width="180">
</el-table-column>
<el-table-column prop="id" label="ID" width="80" />
<el-table-column
prop="date"
label="日期"
sortable
width="180"
show-overflow-tooltip
>
</el-table-column>
<el-table-column prop="address" label="地址" show-overflow-tooltip>
</el-table-column>
</el-table>
<p>{{ selectArr.map(el => el.id) }}</p>
<div style="margin-top: 20px">
<el-button @click="cancelAll()">取消选择</el-button>
</div>
</div>
</template>
<script>
export default {
data() {
return {
tableData: [
{
id: 1,
date: "2016-05-01",
name: "1",
address: "上海市普陀区金沙江路 1 弄",
isRowChecked: false //每一个节点默认设置未勾选
},
{
id: 2,
date: "2016-05-02",
name: "2",
address: "上海市普陀区金沙江路 2 弄",
children: null,
isRowChecked: false
},
{
id: 3,
date: "2016-05-03",
name: "3",
address: "上海市普陀区金沙江路 2 弄",
children: [
{
id: 31,
date: "2016-05-31",
name: "3-1",
address: "上海市普陀区金沙江路 31 弄",
children: []
},
{
id: 32,
date: "2016-05-32",
name: "3-2",
address: "上海市普陀区金沙江路 32 弄",
children: [
{
id: 321,
date: "2016-05-04",
name: "3-2-1",
address: "上海市普陀区金沙江路 321 弄"
}
]
}
]
},
{
id: 4,
date: "2016-05-04",
name: "4",
address: "上海市普陀区金沙江路 4 弄"
}
],
isAllCheck: false, // 全选/取消全选
selectArr: [] // 勾选数组
};
},
created() {
this.initTableData(this.tableData);
},
methods: {
//递归添加每个节点的勾选状态字段
initTableData(parent) {
parent.map(item => {
this.$set(item, "isRowChecked", false);
if (Array.isArray(item.children) && item.children.length > 0) {
this.initTableData(item.children);
}
});
},
selectable(row) {
// el-table 原生方法——设置禁止勾选,此时不起效
// if (Array.isArray(row) && row.length > 0) {
// return false;
// } else {
// return true;
// }
return true;
},
// 切换勾选单个末级节点
clickChildren(row) {
row.isRowChecked = !row.isRowChecked;
this.toggleSelection(row, row.isRowChecked);
},
select(selection, row) {
console.log("这种方法,@select监听不起效");
},
// 全选/取消全选
selectAll() {
this.isAllCheck = !this.isAllCheck;
this.toggleSelectChildren(this.tableData, this.isAllCheck, "allCheck");
},
// 递归全选子节点
toggleSelectChildren(parent, flag, operatorType) {
if (operatorType == "allCheck") {
parent.forEach(item => {
this.toggleSelection(item, flag);
if (Array.isArray(item.children) && item.children.length > 0) {
this.toggleSelectChildren(item.children, flag, operatorType);
}
});
}
},
// 可正常触发@selection-change监听
selectionChange(selection) {
this.selectArr = selection; // 包含父级和末级
this.selectArr = this.selectArr.filter(
item => !item.children || item.children.length < 1
);
console.log(this.selectArr);
},
// 切换单行的勾选状态
toggleSelection(row, select) {
if (row) {
row.isRowChecked = select;
this.$nextTick(() => {
this.$refs.table && this.$refs.table.toggleRowSelection(row, select);
});
}
},
// 取消全选
cancelAll() {
// this.$refs.table.clearSelection(); el-table原生的清空,此时不起效
this.toggleSelectChildren(this.tableData, false, "allCheck");
}
}
};
</script>