效果
原理分析
- 从后端获取数据后,判断当前节点是否勾选,从而判断是否勾选子节点
- 勾选当前节点时,子节点均勾选
全勾选
与半勾选
与不勾选
的样式处理
全勾选
和全取消勾选
的逻辑
- 筛选出半勾选的节点
定义变量
import {
computed, nextTick, reactive, ref} from 'vue';
import {
tree} from "./tree.js";
const tableData = reactive([
{
id: '节点1', hasChildren: true}, {
id: '节点2', hasChildren: true},
{
id: '节点3', hasChildren: true}, {
id: '节点4', hasChildren: true},
]);
const treeTableRef = ref();
const selections = ref([]);
const childrenNodes = reactive({
});
const isSelectedAll = ref(false);
定义是否勾选全部子节点函数
const selectedChildren = (id, selected) => {
(childrenNodes[id] || []).forEach(row => {
treeTableRef.value.toggleRowSelection(row, selected);
if (id !== row.id) selectedChildren(row.id, selected);
});
}
单个节点勾选函数
const select = (selection, row) => {
nextTick(() => {
selectedChildren(row.id, selection.some(d => d.id === row.id));
});
}
从后端获取节点数据
const load = (row, treeNode, resolve) => {
setTimeout(() => {
childrenNodes[row.id] = (tree[row.id] || []).map(d => ({
...d, parentId: row.id}));
resolve(childrenNodes[row.id]);
nextTick(() => select(selections.value, row));
}, 100);
}
全勾选、全取消勾选函数和勾选监听
const selectAll = (selection) => {
isSelectedAll.value = !isSelectedAll.value;
treeTableRef.value.data.forEach(row => {
treeTableRef.value.toggleRowSelection(row, isSelectedAll.value);
selectedChildren(row.id, isSelectedAll.value);
});
}
const selectionChange = (selection) => {
selections.value = selection;
nextTick(() => ((selection.length === 0) && (isSelectedAll.value = false)));
}
表头Checkbox选中样式
const headerRowClassName = computed(() => {
let count = tableData.length;
for (const key in childrenNodes) {
count += (childrenNodes[key] || []).length;
}
return (count === selections.value.length || selections.value.length === 0) ? '' : 'half-checked';
})
定义当前节点样式选择器
const rowClassName = ({
row, rowIndex}) => {
if (selections.value.length === 0) return '';
const selectedNodeFlags = [];
const filterSelectedChildrenNodeFlags = (item) => {
(childrenNodes[item.id] || []).forEach(node => {
if (item.id