React antd tree树组件 - 父子节点没有自动关联情况下 - 显示半选、全选状态以及实现父子节点互动

实现的效果图如下:
在这里插入图片描述
如Ant Design Vue 中所示,并没有提供获取半选节点的方法,当设置checked和checkStrictly时,父子节点也不再自动关联了
在这里插入图片描述

前提:从后端可以获取的数据分别是完整的树型数据、所有选中的节点数据(一个数组、同时包含 父节点和子节点),具体的大概数据可以看下面
树形结构(二重),parId是-1则表示是父节点数据:
在这里插入图片描述
这是返回的已选中节点的数组:
在这里插入图片描述
下面是具体的代码:

state = {treeData: [], // 树形数据checkedKeys: [],checkable: false, // 因为我的页面是树型结构在页面右侧,根据左侧显示具体(看自己需求)loading: true,halfChecked: [], // 半选checked: [] // 全选
};render() {
const { checkedKeys, treeData, checkable, halfChecked, checked, loading } = this.state
<Treeref={r => this.treeRef = r}className={styles.menuTree}blockNodeshowLine// selectable={false}checkable={checkable}defaultExpandAll// checkedKeys={checkedKeys}checkedKeys={{checked,halfChecked}}checkStrictlyonCheck={({ checked: ck, halfChecked: hc, ...oth }, { checked, node: { props: { dataRef } } }) => {// 选择if (checked && dataRef.id) {ck = ck.filter(i => i != `${dataRef.id}`).concat(`${dataRef.id}`);}// 如果有子级,则全部选上if(dataRef.parId == '-1'&&dataRef.childList&&dataRef.childList.length > 0){const kidKeys = this.getCKidKey(dataRef.childList);if(checked){ck = ck.concat(kidKeys);}else{ck = ck.filter(k=>{const bo= !kidKeys.includes(k);return bo;})}}// 如果选中的是子级,其父级也默认选中;取消选中时如果其父级下无选中内容,父级取消选中if(dataRef.parId != '-1'){if(checked){ck.push(dataRef.parId.toString())ck = Array.from(new Set(ck));}else{const ckId = dataRef.id; // 当前选中子级的idconst ckParId = dataRef.parId; // 当前选中de子级的父级idconst childList = this.treeMap[ckParId]?.childList; // 当前选中子级的父级 包含的子级let isHave = false // 父级下的子级是否有选中的,默认无选中的childList.forEach((item => {const ass = ck.includes(item.id.toString())if(ass) { // 如果还有选中的isHave = truereturn}}))if(!isHave){ck = ck.filter(item => item != ckParId)}}}const lastAllData = Array.from(new Set([...ck, ...hc]))this.parentStatus(lastAllData);}}
>{this.renderTreeNodes(treeData)}
</Tree>
}

主要是onCheck方法里面的处理,下面是用到的一些方法

// 所有已选节点分成两组,全选、半选。
parentStatus = (checked) => { // 这里的checked是指传入所有已选节点const { treeData } = this.state; const pData = [] // 半选的父级id数组const allPData = [] // 全选的父级id数组checked.forEach(i => {treeData.forEach(j =>{if(i == j.id){ // 如果有选中的父级const ckPList = [] // 选中父级的子级数组j.childList.forEach(r =>{ckPList.push(r.id.toString())})if(this.isContained(checked, ckPList)){allPData.push(j.id.toString())}else{pData.push(i.toString())}}})})const halfCkData = [] // 半选状态数据const allCkData = [] // 全选状态数据for(const i of checked){pData.includes(i)&&halfCkData.push(i);!pData.includes(i)&&allCkData.push(i);}this.setState({checked: allCkData,halfChecked: halfCkData,})
}// 判断一个数组是否包含了另一个数组的全部元素
isContained = (a, b) => {// a和b其中一个不是数组,直接返回falseif (!(a instanceof Array) || !(b instanceof Array)) return false;const len = b.length;// a的长度小于b的长度,直接返回falseif (a.length < len) return false;for (let i = 0; i < len; i++) {if (!a.includes(b[i])) return false;}return true;
};// 
ckeys = []getKidKey = kids => {kids.reduce((p, c, ci, arr) => {p.push(c.key);if (c.children) {this.getKidKey(c.children);}return p;}, this.ckeys);
}getCKidKey = kids => {this.getKidKey(kids);const cks = [...this.ckeys];this.ckeys = []return cks;
}

ps因为代码是随着需求优化慢慢增加的,所以命名可能有点乱,方法也是比较杂又多,写出来了就随它了,懒得优化就这样了。如果有帮助到你的话就很nice啦~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/68046.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

location rewrite

Nginx location 匹配的规则和优先级 Nginx常用的变量 rewrite: 重定向功能 Location 匹配 URI URI&#xff1a;统一资源的表示符&#xff0c;是一种字符串标识&#xff0c;用于标识抽象或者物理资源 先来巩固一些与location结合使用的正则表达式 正则表达式&#xff1a;匹…

c51单片机串行通信示例代码(单片机--单片机通信)(附带proteus线路图)

//这个发送端代码 #include "reg51.h" #include "myheader.h" #define uchar unsigned char long int sleep_i0; long int main_i0; void main() {uchar sendx[6]{2,0,2,3,8,1};sleep(2000);TMOD0x20;TH10XF4;//根据波特率计算公式这里需要设置为这么多才能…

matlab使用教程(15)—图论基础

1.有向图和无向图 1.1什么是图&#xff1f; 图是表示各种关系的节点和边的集合&#xff1a; • 节点 是与对象对应的顶点。 • 边 是对象之间的连接。 • 图的边有时会有权重 &#xff0c;表示节点之间的每个连接的强度&#xff08;或一些其他属性&#xff09;。 这些定…

linux下安装.run后缀名文件

1.文件传输 对于大文件&#xff0c;不能直接拖拽&#xff0c;可以借助工具&#xff0c;例如WinSCP 创建会话时&#xff0c;需要提供虚拟机的主机名&#xff0c;可以采取输入ifconfig的命令&#xff0c;如图所示&#xff1a; ifconfig&#xff08;接口配置&#xff09;命令在 …

2023-08-11 LeetCode每日一题(矩阵对角线元素的和)

2023-08-11每日一题 一、题目编号 1572. 矩阵对角线元素的和二、题目链接 点击跳转到题目位置 三、题目描述 给你一个正方形矩阵 mat&#xff0c;请你返回矩阵对角线元素的和。 请你返回在矩阵主对角线上的元素和副对角线上且不在主对角线上元素的和。 示例 1&#xff1…

最强自动化测试框架Playwright (27)-跟踪查看器

Playwright Trace Viewer 是一个 GUI 工具&#xff0c;可帮助您在脚本运行后探索记录的 Playwright 跟踪。可以本地打开&#xff0c;也可以在trace.playwright.dev.打开&#xff0c; 录制跟踪文件 使用context.tracing.start进行录制&#xff0c;使用stop方法保存录制文件 b…

Electron基础篇

人生有些事,错过一时,就错过一世。 官网&#xff1a;简介 | Electron Electron-大多用来写桌面端软件 Electron介绍 Electront的核心组成是Chromium、Node.js以及内置的Native API&#xff0c;其中Chromium为Electron提供强大的UI能力&#xff0c;可以在不考虑兼容的情况下利…

分布式监控平台—zabbix

前言一、zabbix概述1.1 什么是zabbix1.2 zabbix的监控原理1.3 zabbix常见五个应用程序1.4 zabbix的监控模式1.5 监控架构1.5.1 C/S&#xff08;server—client&#xff09;1.5.2 server—proxy—client1.5.3 master—node—client 二、部署zabbix2.1 部署 zabbix server 端2.2 …

什么是React?React与VU的优缺点有哪些?

什么是React&#xff1f;什么是VUE&#xff1f; 维基百科上的概念解释&#xff0c;Vue.js是一个用于创建用户界面的开源MVVM前端JavaScript框架&#xff0c;也是一个创建单页应用的Web应用框架。Vue.js由尤雨溪&#xff08;Evan You&#xff09;创建&#xff0c;由他和其他活跃…

【已解决】mac端 sourceTree 解决remote: HTTP Basic: Access denied报错

又是在一次使用sourcetree拉取或者提交代码时候&#xff0c;遇到了sourcetree报错&#xff1b; 排查了一会&#xff0c;比如查看了SSH keys是否有问题、是否与sourcetree账户状态有问题等等&#xff0c;最终才发现并解决问题 原因&#xff1a; 因为之前公司要求企业gitlab中…

vue3 + ts+element-plus学习笔记

子组件通过defineProps方法接收父组件传递过来的数据&#xff0c;是vue3中提供的方法&#xff0c;不需要引入&#xff0c;直接使用 方法的写法&#xff1a; const onClick (){... }自定义事件&#xff1a; 子组件点击事件 全局事件总线 mitt 兄弟组件之间的事件&#x…

无涯教程-Perl - setpwent函数

描述 此功能将枚举设置(或重置)到密码条目集的开头。应该在第一次调用getpwent之前调用此函数。 语法 以下是此函数的简单语法- setpwent返回值 此函数不返回任何值。 例 以下是显示其基本用法的示例代码- #!/usr/bin/perlwhile(($name, $passwd, $uid, $gid, $quota, …