溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Antd如何使用Table組件嵌套Table以及選擇框聯(lián)動

發(fā)布時間:2020-10-26 14:31:13 來源:億速云 閱讀:787 作者:Leah 欄目:開發(fā)技術

這篇文章運用簡單易懂的例子給大家介紹Antd如何使用Table組件嵌套Table以及選擇框聯(lián)動,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

一、需求

在使用Table組件嵌套Table時,父子Table的選擇框需要聯(lián)動,即父Table選中,該行下的子Table需要全選中,某一個子Table全部選中,則該子Table所在的父Table那一行也需要選中。

二、Table的rowSelection配置

父子Table聯(lián)動,就不能使用OnChange,需要使用OnSelect以及OnSelectAll手動配置。

selectedRowKeys:指定選中項的key數組

OnSelect:手動選擇/取消選擇某行的回調

OnSelect(record, selected, selectedRows)

record:選中的當前行數據

selected:選中狀態(tài),true:選中,false:取消選中     

selectedRows:選擇的數組

OnSelectAll:手動選擇/取消選擇所有行的回調      

OnSelect(selected, selectedRows, changeRows)       

selected:選中狀態(tài),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: '關聯(lián)門店數',
  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、創(chuàng)建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的選擇框聯(lián)動就完成了,

注意: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: '關聯(lián)門店數',
  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選中狀態(tài)
 //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以及選擇框聯(lián)動就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI