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界面
import react, { useeffect, usestate } from 'react'; import { table, } from 'antd' export default () => { const datasource: any = [ { key: '1', title: '餐饮酒店/服务员', number: '8家门店,共8人', time: '2020.05.25 15:35', childdata: [ { key: '1.1', jobtitle: '大桶大足浴-保安', num: '2人', }, { key: '1.2', jobtitle: '大桶大足浴-保安', num: '5人', }, ] }, { key: '2', title: '餐饮酒店/收银员', number: '无门店,共5人', time: '2020.06.06 11:35', childdata: [ { key: '2.1', jobtitle: '大桶大足浴', num: '0人', }, { key: '2.2', jobtitle: '大桶大足浴', num: '1人', }, ] }, ] const parentcolumns: any = [ { title: '工种', dataindex: 'title', key: 'title', }, { title: '关联门店数', dataindex: 'number', key: 'number', }, { title: '时间', dataindex: 'time', key: 'time', }, ] const expandedrowrender = (record: any, index: any, indent: any, expanded: any) => { const childdata = record.childdata const childcolumns: any = [ { title: '岗位名称', dataindex: 'jobtitle', key: 'jobtitle' }, { title: '招聘人数', dataindex: 'num', key: 'num' }, ] return <table columns={childcolumns} datasource={childdata} pagination={false} rowselection={childrowselection} /> } return ( <div> <table columns={parentcolumns} datasource={datasource} expandable={{ expandedrowrender }} rowselection={parentrowselection} /> </div> ); }
四、开始配置rowselection
1、配置父子table的rowselection
const childrowselection = { selectedrowkeys: childselectedrowkeys, onselect: onchildselectchange, onselectall: onchildselectall } const parentrowselection = { selectedrowkeys: parentselectedrowkeys, onselect: onparentselectchange, onselectall: onparentselectall, }
2、创建childselectedrowkeys,parentselectedrowkeys变量,用来存放父子table选中的key值
const [parentselectedrowkeys, setparentselectedrowkeys] = usestate<any>([])
const [childselectedrowkeys, setchildselectedrowkeys] = usestate<any>([])
3、设置子table手动选择/取消某行的回调 onchildselectchange
选择单个时,当前行选中,若将该table的所有选项全部选中,则子table对应的父table所在的那一行也选中
const onchildselectchange = (record: any, selected: any, selectedrows: any) => { let childarr: any = [...childselectedrowkeys]; //第一步 判断selected true:选中,将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 (let item of datasource) { if (item.childdata.find((d: any) => d.key === record.key)) { let parentarr: 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行也取消选中
const onchildselectall = (selected: any, selectedrows: any, changerows: any) => { //第一步:判断selected,true:将子table全部选中,false:将子table全部取消选中 let childarr: any = [...childselectedrowkeys]; if (selected) { //全选 childarr = array.from(new set([...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 (let item of datasource) { if (item.childdata.find((d: any) => d.key === changerows[0].key)) { let parentarr: 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也全部取消选中
const onparentselectchange = (record: any, selected: any, selectedrows: any) => { let patentarr: any = [...parentselectedrowkeys]; let childarr: any = [...childselectedrowkeys]; //setchildarr:选择父table下的所有子选项 let setchildarr = datasource.find((d: any) => d.key === record.key).childdata.map((item: any) => item.key) //第一步 判断selected true:选中,false,取消选中 if (selected) { //第二步,父table选中,子table全选中(全部整合到一起,然后去重) patentarr.push(record.key) childarr = array.from(new set([...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也取消选中
const onparentselectall = (selected: any, selectedrows: any, changerows: any) => { let patentarr: any = [...parentselectedrowkeys]; let setchildarr: any = []; //将改变的父table下的子table下的key都添加到setchildarr中 changerows.foreach((e: any) => { setchildarr = [...setchildarr, ...e.childdata.map((item: any) => item.key)] }); //第一步判断selected true:全选,false:取消全选 if (selected) { //第二步:父table选中,子table全选中,设置子table的selectedrowkeys patentarr = array.from(new set([...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完整代码
import react, { useeffect, usestate } from 'react'; import { table, button } from 'antd' import { plusoutlined } from '@ant-design/icons'; export default () => { const [parentselectedrowkeys, setparentselectedrowkeys] = usestate<any>([]) const [childselectedrowkeys, setchildselectedrowkeys] = usestate<any>([]) console.log(parentselectedrowkeys, 'parentselectedrowkeys') console.log(childselectedrowkeys, 'childselectedrowkeys') const datasource: any = [ { key: '1', title: '餐饮酒店/服务员', number: '8家门店,共8人', time: '2020.05.25 15:35', childdata: [ { key: '1.1', jobtitle: '大桶大足浴-保安', num: '2人', }, { key: '1.2', jobtitle: '大桶大足浴-保安', num: '5人', }, ] }, { key: '2', title: '餐饮酒店/收银员', number: '无门店,共5人', time: '2020.06.06 11:35', childdata: [ { key: '2.1', jobtitle: '大桶大足浴', num: '0人', }, { key: '2.2', jobtitle: '大桶大足浴', num: '1人', }, ] }, ] const parentcolumns: any = [ { title: '工种', dataindex: 'title', key: 'title', }, { title: '关联门店数', dataindex: 'number', key: 'number', }, { title: '时间', dataindex: 'time', key: 'time', }, ] const expandedrowrender = (record: any, index: any, indent: any, expanded: any) => { const childdata = record.childdata const childcolumns: any = [ { title: '岗位名称', dataindex: 'jobtitle', key: 'jobtitle' }, { title: '招聘人数', dataindex: 'num', key: 'num' }, ] return <table columns={childcolumns} datasource={childdata} pagination={false} rowselection={childrowselection} /> } const onparentselectchange = (record: any, selected: any, selectedrows: any) => { let patentarr: any = [...parentselectedrowkeys]; let childarr: any = [...childselectedrowkeys]; //setchildarr:选择父table下的所有子选项 let setchildarr = datasource.find((d: any) => d.key === record.key).childdata.map((item: any) => item.key) //第一步 判断selected true:选中,false,取消选中 if (selected) { //第二步,父table选中,子table全选中 patentarr.push(record.key) childarr = array.from(new set([...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) } const onparentselectall = (selected: any, selectedrows: any, changerows: any) => { let patentarr: any = [...parentselectedrowkeys]; let setchildarr: any = []; changerows.foreach((e: any) => { setchildarr = [...setchildarr, ...e.childdata.map((item: any) => item.key)] }); //第一步判断selected true:全选,false:取消全选 if (selected) { //第二步:父table选中,子table全选中,设置子table的selectedrowkeys patentarr = array.from(new set([...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) } const onchildselectchange = (record: any, selected: any, selectedrows: any) => { //record:当前操作行 //selected选中状态 //selectedrows:选择的数组 let childarr: any = [...childselectedrowkeys]; //第一步 判断selected true:选中,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 (let item of datasource) { if (item.childdata.find((d: any) => d.key === record.key)) { let parentarr: 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) } const onchildselectall = (selected: any, selectedrows: any, changerows: any) => { //selected:全选true 取消全选false //selectedrows:改变后的 //changerows:改变的所有数组 //第一步:判断selected,true:将子table全部选中,false:将子table全部取消选中 let childarr: any = [...childselectedrowkeys]; if (selected) { //全选 childarr = array.from(new set([...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 (let item of datasource) { if (item.childdata.find((d: any) => d.key === changerows[0].key)) { let parentarr: any = [...parentselectedrowkeys]; if (selected) { //全选 parentarr.push(item.key) } else { //取消全选 parentarr.splice(parentarr.findindex((item: any) => item === item.key), 1) } setparentselectedrowkeys(parentarr) break; } } setchildselectedrowkeys(childarr) } const childrowselection = { selectedrowkeys: childselectedrowkeys, onselect: onchildselectchange, onselectall: onchildselectall } const parentrowselection = { selectedrowkeys: parentselectedrowkeys, onselect: onparentselectchange, onselectall: onparentselectall, } return ( <div> <table columns={parentcolumns} datasource={datasource} expandable={{ expandedrowrender }} rowselection={parentrowselection} /> </div> ); }
以上这篇antd的table组件嵌套table以及选择框联动操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。