【定制需求】el-tree 树形控件实现:每级可单独选择,选择父级不选中子集,子集全部选中不自动选中父级,手写按钮可支持子集全选,以及取消子集全选,el-tree 树形控件取消父子级联动选择

背景: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>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

G佳伟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值