效果
原理分析
- 从后端获取数据后,判断当前节点是否勾选,从而判断是否勾选子节点
- 勾选当前节点时,子节点均勾选
全勾选
与半勾选
与不勾选
的样式处理全勾选
和全取消勾选
的逻辑- 筛选出半勾选的节点
定义变量
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