背景:el-tree 树形控件实现:每级可单独选择,选择父级不选中子集,子集全部选中不自动选中父级,手写按钮可支持子集全选以及取消子集全选,el-tree 树形控件取消父子级联动选择,父级子集可随意选择
在网上找了很多资料也没有找到实现的效果,不知道是搜索的不对还是什么情况
以下是根据自己的思路手撸的一个效果
实现思路
使用el-tree实现树形结构效果,然后内嵌el-checkbox实现任意等级多选单选,在使用按钮操作实现子集全选反选
实现效果
el-tree 树形控件实现:每级可单独选择,选择父级不选中
代码
HTML代码
<!-- 使用Element UI的el-tree组件展示树形结构数据,支持多选和操作子节点 -->
<el-tree :data="treeData" node-key="id" :expand-on-click-node="false" highlight-current :props="treeProps">
<!-- 自定义节点内容显示方式 -->
<span class="custom-tree-node" slot-scope="{ node, data }">
<!-- 使用el-checkbox组件实现节点的多选功能 -->
<el-checkbox :label="data.id" v-model="selectedIds" @change="handleCheckboxChange(data.id)">{{ node.label }}</el-checkbox>
<!-- 当节点有子节点时,显示全选和取消全选按钮 -->
<span v-if="hasChildren(data)">
<el-button type="text" size="mini" @click="selectAllChildren(data)">
全选子集
</el-button>
<el-button type="text" size="mini" @click="invertChildrenSelection(data)">
取消全选
</el-button>
</span>
</span>
</el-tree>
js代码
<script>
export default {
data() {
return {
// 树形结构的数据源
treeData: [
// 示例数据
],
// 已选中节点的ID集合
selectedIds: [],
// 定义树形结构中子节点和标签的属性名
treeProps: {
children: 'children',
label: 'name'
},
};
},
methods: {
// 处理复选框选中状态变化的事件
handleCheckboxChange(id) {
// 根据需要实现checkbox变化逻辑
},
// 判断节点是否拥有子节点
hasChildren(data) {
return data.hasOwnProperty('children') && data.children.length > 0;
},
// 选中当前节点的所有子节点
selectAllChildren(items) {
const childIds = this.collectChildIdsRecursive(items.children);
this.selectedIds = [...new Set([...this.selectedIds, ...childIds])];
},
// 取消选中当前节点的所有子节点
invertChildrenSelection(items) {
const childIds = this.collectChildIdsRecursive(items.children);
this.selectedIds = this.selectedIds.filter(id => !childIds.includes(id));
},
// 递归收集节点及其子节点的ID
collectChildIdsRecursive(items, result = []) {
items.forEach(item => {
result.push(item.id);
if (item.children) this.collectChildIdsRecursive(item.children, result);
});
return result;
},
},
};
</script>
css代码
<style lang="scss" scoped>
.custom-tree-node {
flex: 1;
display: flex;
}
</style>
完整代码
<template>
<div class="variable_all height100">
<!-- 使用Element UI的el-tree组件展示树形结构数据,支持多选和操作子节点 -->
<el-tree :data="treeData" node-key="id" :expand-on-click-node="false" highlight-current :props="treeProps">
<!-- 自定义节点内容显示方式 -->
<span class="custom-tree-node" slot-scope="{ node, data }">
<!-- 使用el-checkbox组件实现节点的多选功能 -->
<el-checkbox :label="data.id" v-model="selectedIds" @change="handleCheckboxChange(data.id)">{{ node.label }}</el-checkbox>
<!-- 当节点有子节点时,显示全选和取消全选按钮 -->
<span v-if="hasChildren(data)">
<el-button type="text" size="mini" @click="selectAllChildren(data)">
全选子集
</el-button>
<el-button type="text" size="mini" @click="invertChildrenSelection(data)">
取消全选
</el-button>
</span>
</span>
</el-tree>
</div>
</template>
<script>
export default {
data() {
return {
// 树形结构的数据源
treeData: [
// 示例数据
],
// 已选中节点的ID集合
selectedIds: [],
// 定义树形结构中子节点和标签的属性名
treeProps: {
children: 'children',
label: 'name'
},
};
},
methods: {
// 处理复选框选中状态变化的事件
handleCheckboxChange(id) {
// 根据需要实现checkbox变化逻辑
},
// 判断节点是否拥有子节点
hasChildren(data) {
return data.hasOwnProperty('children') && data.children.length > 0;
},
// 选中当前节点的所有子节点
selectAllChildren(items) {
const childIds = this.collectChildIdsRecursive(items.children);
this.selectedIds = [...new Set([...this.selectedIds, ...childIds])];
},
// 取消选中当前节点的所有子节点
invertChildrenSelection(items) {
const childIds = this.collectChildIdsRecursive(items.children);
this.selectedIds = this.selectedIds.filter(id => !childIds.includes(id));
},
// 递归收集节点及其子节点的ID
collectChildIdsRecursive(items, result = []) {
items.forEach(item => {
result.push(item.id);
if (item.children) this.collectChildIdsRecursive(item.children, result);
});
return result;
},
},
};
</script>
<style lang="scss" scoped>
.custom-tree-node {
flex: 1;
display: flex;
}
</style>