Antd的Table组件嵌套Table以及选择框联动操作
一、需求
在使用Table组件嵌套Table时,父子Table的选择框需要联动,即父Table选中,该行下的子Table需要全选中,某一个子Table全部选中,则该子Table所在的父Table那一行也需要选中。
二、Table的rowSelection配置
父子Table联动,就不能使用OnChange,需要使用OnSelect以及OnSelectAll手动配置。
selectedRowKeys:指定选中项的key数组
OnSelect:手动选择/取消选择某行的回调
OnSelect(record,selected,selectedRows)
record:选中的当前行数据
selected:选中状态,true:选中,false:取消选中
selectedRows:选择的数组
OnSelectAll:手动选择/取消选择所有行的回调
OnSelect(selected,selectedRows,changeRows)
selected:选中状态,true:选中,false:取消选中
selectedRows:选择的数组
changeRows:改变的所有数组
三、根据antd文档搭建Table嵌套Table界面
importReact,{useEffect,useState}from'react';
import{Table,}from'antd'
exportdefault()=>{
constdataSource:any=[
{
key:'1',
title:'餐饮酒店/服务员',
number:'8家门店,共8人',
time:'2020.05.2515:35',
childData:[
{
key:'1.1',
jobTitle:'大桶大足浴-保安',
num:'2人',
},
{
key:'1.2',
jobTitle:'大桶大足浴-保安',
num:'5人',
},
]
},
{
key:'2',
title:'餐饮酒店/收银员',
number:'无门店,共5人',
time:'2020.06.0611:35',
childData:[
{
key:'2.1',
jobTitle:'大桶大足浴',
num:'0人',
},
{
key:'2.2',
jobTitle:'大桶大足浴',
num:'1人',
},
]
},
]
constparentColumns:any=[
{
title:'工种',
dataIndex:'title',
key:'title',
},
{
title:'关联门店数',
dataIndex:'number',
key:'number',
},
{
title:'时间',
dataIndex:'time',
key:'time',
},
]
constexpandedRowRender=(record:any,index:any,indent:any,expanded:any)=>{
constchildData=record.childData
constchildColumns:any=[
{
title:'岗位名称',
dataIndex:'jobTitle',
key:'jobTitle'
},
{
title:'招聘人数',
dataIndex:'num',
key:'num'
},
]
return
}
return(
);
}
四、开始配置rowSelection
1、配置父子Table的rowSelection
constchildRowSelection={
selectedRowKeys:childSelectedRowKeys,
onSelect:onChildSelectChange,
onSelectAll:onChildSelectAll
}
constparentRowSelection={
selectedRowKeys:parentSelectedRowKeys,
onSelect:onParentSelectChange,
onSelectAll:onParentSelectAll,
}
2、创建childSelectedRowKeys,parentSelectedRowKeys变量,用来存放父子Table选中的key值
const[parentSelectedRowKeys,setParentSelectedRowKeys]=useState
([]) const[childSelectedRowKeys,setChildSelectedRowKeys]=useState
([])
3、设置子Table手动选择/取消某行的回调onChildSelectChange
选择单个时,当前行选中,若将该Table的所有选项全部选中,则子Table对应的父Table所在的那一行也选中
constonChildSelectChange=(record:any,selected:any,selectedRows:any)=>{
letchildArr:any=[...childSelectedRowKeys];
//第一步判断selectedtrue:选中,将key值添加到childArr,false:取消选中,将key值从childArr中移除
if(selected){
childArr.push(record.key)
}else{
childArr.splice(childArr.findIndex((item:any)=>item===record.key),1)
}
//必须去除undefined,否则selectedRows会将其他子Table中选中的key值放到数组中,但是值为undefined,如:[undefined,1,uundefined]
selectedRows=selectedRows.filter((a:any)=>a!==undefined)
//第二步,判断selectedRows的长度是否为data中child的长度,相等,就将父table选中,不等就不选中
for(letitemofdataSource){
if(item.childData.find((d:any)=>d.key===record.key)){
letparentArr:any=[...parentSelectedRowKeys];
if(item.childData.length===selectedRows.length){
parentArr.push(item.key)
}else{
if(parentArr.length&&parentArr.find((d:any)=>d===item.key)){
parentArr.splice(parentArr.findIndex((item1:any)=>item1===item.key),1)
}
}
setParentSelectedRowKeys(parentArr)
break;
}
}
setChildSelectedRowKeys(childArr)
}
4、设置子Table手动选择/取消选择所有行的回调onChildSelectAll
当选择全选时,子Table全部选中,并且该子table对应的父table行也选中,取消全选时,子Table全部取消选中,父Table行也取消选中
constonChildSelectAll=(selected:any,selectedRows:any,changeRows:any)=>{
//第一步:判断selected,true:将子Table全部选中,false:将子Table全部取消选中
letchildArr:any=[...childSelectedRowKeys];
if(selected){
//全选
childArr=Array.from(newSet([...childArr,...changeRows.map((item:any)=>item.key)]))
}else{
//取消全选
childArr=childArr.filter((item:any)=>!changeRows.some((e:any)=>e.key===item))
}
//第二步:找到子Table对应的父Table的所在行,再判断selected,true:将父Table所在行选中,false:将父Table所在行取消选中
for(letitemofdataSource){
if(item.childData.find((d:any)=>d.key===changeRows[0].key)){
letparentArr:any=[...parentSelectedRowKeys];
if(selected){
//全选
parentArr.push(item.key)
}else{
//取消全选
parentArr.splice(parentArr.findIndex((item:any)=>item===item.key),1)
}
setParentSelectedRowKeys(parentArr)
break;
}
}
setChildSelectedRowKeys(childArr)
}
5、设置父Table手动选择/取消某行的回调onParentSelctChange
当选择父Table某一行时,该行下的子Table全部选中,取消选择时,该行下的子Table也全部取消选中
constonParentSelectChange=(record:any,selected:any,selectedRows:any)=>{
letpatentArr:any=[...parentSelectedRowKeys];
letchildArr:any=[...childSelectedRowKeys];
//setChildArr:选择父Table下的所有子选项
letsetChildArr=dataSource.find((d:any)=>d.key===record.key).childData.map((item:any)=>item.key)
//第一步判断selectedtrue:选中,false,取消选中
if(selected){
//第二步,父Table选中,子Table全选中(全部整合到一起,然后去重)
patentArr.push(record.key)
childArr=Array.from(newSet([...setChildArr,...childArr]))
}else{
//第二步,父Table取消选中,子Table全取消选中(针对childArr,过滤掉取消选中的父Table下的所有子Table的key)
patentArr.splice(patentArr.findIndex((item:any)=>item===record.key),1)
childArr=childArr.filter((item:any)=>!setChildArr.some((e:any)=>e===item))
}
//第三步,设置父,子的SelectedRowKeys
setParentSelectedRowKeys(patentArr)
setChildSelectedRowKeys(childArr)
}
6、设置父Table手动选择/取消选择所有行的回调onParentSelectAll
全选时,父Table全部选中,所有对应的子Table也全部选中。取消全选时,父Table取消选中,所有子Table也取消选中
constonParentSelectAll=(selected:any,selectedRows:any,changeRows:any)=>{
letpatentArr:any=[...parentSelectedRowKeys];
letsetChildArr:any=[];
//将改变的父Table下的子Table下的key都添加到setChildArr中
changeRows.forEach((e:any)=>{
setChildArr=[...setChildArr,...e.childData.map((item:any)=>item.key)]
});
//第一步判断selectedtrue:全选,false:取消全选
if(selected){
//第二步:父Table选中,子Table全选中,设置子Table的SelectedRowKeys
patentArr=Array.from(newSet([...patentArr,...changeRows.map((item:any)=>item.key)]))
setChildSelectedRowKeys(setChildArr)
}else{
//第二步:父Table取消选中,子Table全取消选中,设置子Table的SelectedRowKeys
patentArr=patentArr.filter((item:any)=>!changeRows.some((e:any)=>e.key===item))
setChildSelectedRowKeys([])
}
//第三步:设置父Table的SelectedRowKeys
setParentSelectedRowKeys(patentArr)
}
这样,父子Table的选择框联动就完成了,
注意:dataSource数据格式根据自己的格式而定
五、完整Demo
Table嵌套Table完整代码
importReact,{useEffect,useState}from'react';
import{Table,Button}from'antd'
import{PlusOutlined}from'@ant-design/icons';
exportdefault()=>{
const[parentSelectedRowKeys,setParentSelectedRowKeys]=useState([])
const[childSelectedRowKeys,setChildSelectedRowKeys]=useState([])
console.log(parentSelectedRowKeys,'parentSelectedRowKeys')
console.log(childSelectedRowKeys,'childSelectedRowKeys')
constdataSource:any=[
{
key:'1',
title:'餐饮酒店/服务员',
number:'8家门店,共8人',
time:'2020.05.2515:35',
childData:[
{
key:'1.1',
jobTitle:'大桶大足浴-保安',
num:'2人',
},
{
key:'1.2',
jobTitle:'大桶大足浴-保安',
num:'5人',
},
]
},
{
key:'2',
title:'餐饮酒店/收银员',
number:'无门店,共5人',
time:'2020.06.0611:35',
childData:[
{
key:'2.1',
jobTitle:'大桶大足浴',
num:'0人',
},
{
key:'2.2',
jobTitle:'大桶大足浴',
num:'1人',
},
]
},
]
constparentColumns:any=[
{
title:'工种',
dataIndex:'title',
key:'title',
},
{
title:'关联门店数',
dataIndex:'number',
key:'number',
},
{
title:'时间',
dataIndex:'time',
key:'time',
},
]
constexpandedRowRender=(record:any,index:any,indent:any,expanded:any)=>{
constchildData=record.childData
constchildColumns:any=[
{
title:'岗位名称',
dataIndex:'jobTitle',
key:'jobTitle'
},
{
title:'招聘人数',
dataIndex:'num',
key:'num'
},
]
return
}
constonParentSelectChange=(record:any,selected:any,selectedRows:any)=>{
letpatentArr:any=[...parentSelectedRowKeys];
letchildArr:any=[...childSelectedRowKeys];
//setChildArr:选择父Table下的所有子选项
letsetChildArr=dataSource.find((d:any)=>d.key===record.key).childData.map((item:any)=>item.key)
//第一步判断selectedtrue:选中,false,取消选中
if(selected){
//第二步,父Table选中,子Table全选中
patentArr.push(record.key)
childArr=Array.from(newSet([...setChildArr,...childArr]))
}else{
//第二步,父Table取消选中,子Table全取消选中
patentArr.splice(patentArr.findIndex((item:any)=>item===record.key),1)
childArr=childArr.filter((item:any)=>!setChildArr.some((e:any)=>e===item))
}
//第三步,设置父,子的SelectedRowKeys
setParentSelectedRowKeys(patentArr)
setChildSelectedRowKeys(childArr)
}
constonParentSelectAll=(selected:any,selectedRows:any,changeRows:any)=>{
letpatentArr:any=[...parentSelectedRowKeys];
letsetChildArr:any=[];
changeRows.forEach((e:any)=>{
setChildArr=[...setChildArr,...e.childData.map((item:any)=>item.key)]
});
//第一步判断selectedtrue:全选,false:取消全选
if(selected){
//第二步:父Table选中,子Table全选中,设置子Table的SelectedRowKeys
patentArr=Array.from(newSet([...patentArr,...changeRows.map((item:any)=>item.key)]))
setChildSelectedRowKeys(setChildArr)
}else{
//第二步:父Table取消选中,子Table全取消选中,设置子Table的SelectedRowKeys
patentArr=patentArr.filter((item:any)=>!changeRows.some((e:any)=>e.key===item))
setChildSelectedRowKeys([])
}
//第三步:设置父Table的SelectedRowKeys
setParentSelectedRowKeys(patentArr)
}
constonChildSelectChange=(record:any,selected:any,selectedRows:any)=>{
//record:当前操作行
//selected选中状态
//selectedRows:选择的数组
letchildArr:any=[...childSelectedRowKeys];
//第一步判断selectedtrue:选中,false:取消选中
if(selected){
childArr.push(record.key)
}else{
childArr.splice(childArr.findIndex((item:any)=>item===record.key),1)
}
selectedRows=selectedRows.filter((a:any)=>a!==undefined)
//第二步,判断selectedRows的长度是否为data中child的长度,相等,就将父table选中,不等就不选中
for(letitemofdataSource){
if(item.childData.find((d:any)=>d.key===record.key)){
letparentArr:any=[...parentSelectedRowKeys];
if(item.childData.length===selectedRows.length){
parentArr.push(item.key)
}else{
if(parentArr.length&&parentArr.find((d:any)=>d===item.key)){
parentArr.splice(parentArr.findIndex((item1:any)=>item1===item.key),1)
}
}
setParentSelectedRowKeys(parentArr)
break;
}
}
setChildSelectedRowKeys(childArr)
}
constonChildSelectAll=(selected:any,selectedRows:any,changeRows:any)=>{
//selected:全选true取消全选false
//selectedRows:改变后的
//changeRows:改变的所有数组
//第一步:判断selected,true:将子Table全部选中,false:将子Table全部取消选中
letchildArr:any=[...childSelectedRowKeys];
if(selected){
//全选
childArr=Array.from(newSet([...childArr,...changeRows.map((item:any)=>item.key)]))
}else{
//取消全选
childArr=childArr.filter((item:any)=>!changeRows.some((e:any)=>e.key===item))
}
//第二步:找到子Table对应的父Table的所在行,再判断selected,true:将父Table所在行选中,false:将父Table所在行取消选中
for(letitemofdataSource){
if(item.childData.find((d:any)=>d.key===changeRows[0].key)){
letparentArr:any=[...parentSelectedRowKeys];
if(selected){
//全选
parentArr.push(item.key)
}else{
//取消全选
parentArr.splice(parentArr.findIndex((item:any)=>item===item.key),1)
}
setParentSelectedRowKeys(parentArr)
break;
}
}
setChildSelectedRowKeys(childArr)
}
constchildRowSelection={
selectedRowKeys:childSelectedRowKeys,
onSelect:onChildSelectChange,
onSelectAll:onChildSelectAll
}
constparentRowSelection={
selectedRowKeys:parentSelectedRowKeys,
onSelect:onParentSelectChange,
onSelectAll:onParentSelectAll,
}
return(
);
}
以上这篇Antd的Table组件嵌套Table以及选择框联动操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。