背景: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>