Antd的Table組件嵌套Table以及選擇框聯(lián)動(dòng)操作
一、需求
在使用Table組件嵌套Table時(shí),父子Table的選擇框需要聯(lián)動(dòng),即父Table選中,該行下的子Table需要全選中,某一個(gè)子Table全部選中,則該子Table所在的父Table那一行也需要選中。
二、Table的rowSelection配置
父子Table聯(lián)動(dòng),就不能使用OnChange,需要使用OnSelect以及OnSelectAll手動(dòng)配置。
selectedRowKeys:指定選中項(xiàng)的key數(shù)組
OnSelect:手動(dòng)選擇/取消選擇某行的回調(diào)
OnSelect(record, selected, selectedRows)
record:選中的當(dāng)前行數(shù)據(jù)
selected:選中狀態(tài),true:選中,false:取消選中
selectedRows:選擇的數(shù)組
OnSelectAll:手動(dòng)選擇/取消選擇所有行的回調(diào)
OnSelect(selected, selectedRows, changeRows)
selected:選中狀態(tài),true:選中,false:取消選中
selectedRows:選擇的數(shù)組
changeRows:改變的所有數(shù)組
三、根據(jù)antd文檔搭建Table嵌套Table界面
import React, { useEffect, useState } from 'react'; import { Table, } from 'antd' export default () => { const dataSource: any = [ { key: '1', title: '餐飲酒店/服務(wù)員', 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: '無(wú)門店,共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: '關(guān)聯(lián)門店數(shù)', dataIndex: 'number', key: 'number', }, { title: '時(shí)間', 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: '招聘人數(shù)', 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> ); }
四、開(kāi)始配置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變量,用來(lái)存放父子Table選中的key值
const [parentSelectedRowKeys, setParentSelectedRowKeys] = useState<any>([])
const [childSelectedRowKeys, setChildSelectedRowKeys] = useState<any>([])
3、設(shè)置子Table手動(dòng)選擇/取消某行的回調(diào) onChildSelectChange
選擇單個(gè)時(shí),當(dāng)前行選中,若將該Table的所有選項(xiàng)全部選中,則子Table對(duì)應(yīng)的父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會(huì)將其他子Table中選中的key值放到數(shù)組中,但是值為undefined,如:[ undefined,1,uundefined] selectedRows = selectedRows.filter((a: any) => a !== undefined) //第二步,判斷selectedRows的長(zhǎng)度是否為data中child的長(zhǎng)度,相等,就將父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、設(shè)置子Table手動(dòng)選擇/取消選擇所有行的回調(diào)onChildSelectAll
當(dāng)選擇全選時(shí),子Table全部選中,并且該子table對(duì)應(yīng)的父table行也選中,取消全選時(shí),子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對(duì)應(yīng)的父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、設(shè)置父Table手動(dòng)選擇/取消某行的回調(diào) onParentSelctChange
當(dāng)選擇父Table某一行時(shí),該行下的子Table全部選中,取消選擇時(shí),該行下的子Table也全部取消選中
const onParentSelectChange = (record: any, selected: any, selectedRows: any) => { let patentArr: any = [...parentSelectedRowKeys]; let childArr: any = [...childSelectedRowKeys]; //setChildArr:選擇父Table下的所有子選項(xiàng) 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全取消選中(針對(duì)childArr,過(guò)濾掉取消選中的父Table下的所有子Table的key) patentArr.splice(patentArr.findIndex((item: any) => item === record.key), 1) childArr = childArr.filter((item: any) => !setChildArr.some((e: any) => e === item)) } //第三步,設(shè)置父,子的SelectedRowKeys setParentSelectedRowKeys(patentArr) setChildSelectedRowKeys(childArr) }
6、設(shè)置父Table手動(dòng)選擇/取消選擇所有行的回調(diào)onParentSelectAll
全選時(shí),父Table全部選中,所有對(duì)應(yīng)的子Table也全部選中。取消全選時(shí),父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全選中,設(shè)置子Table的SelectedRowKeys patentArr = Array.from(new Set([...patentArr, ...changeRows.map((item: any) => item.key)])) setChildSelectedRowKeys(setChildArr) } else { //第二步:父Table取消選中,子Table全取消選中,設(shè)置子Table的SelectedRowKeys patentArr = patentArr.filter((item: any) => !changeRows.some((e: any) => e.key === item)) setChildSelectedRowKeys([]) } //第三步:設(shè)置父Table的SelectedRowKeys setParentSelectedRowKeys(patentArr) }
這樣,父子Table的選擇框聯(lián)動(dòng)就完成了,
注意:dataSource數(shù)據(jù)格式根據(jù)自己的格式而定
五、完整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: '餐飲酒店/服務(wù)員', 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: '無(wú)門店,共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: '關(guān)聯(lián)門店數(shù)', dataIndex: 'number', key: 'number', }, { title: '時(shí)間', 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: '招聘人數(shù)', 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下的所有子選項(xiàng) 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)) } //第三步,設(shè)置父,子的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全選中,設(shè)置子Table的SelectedRowKeys patentArr = Array.from(new Set([...patentArr, ...changeRows.map((item: any) => item.key)])) setChildSelectedRowKeys(setChildArr) } else { //第二步:父Table取消選中,子Table全取消選中,設(shè)置子Table的SelectedRowKeys patentArr = patentArr.filter((item: any) => !changeRows.some((e: any) => e.key === item)) setChildSelectedRowKeys([]) } //第三步:設(shè)置父Table的SelectedRowKeys setParentSelectedRowKeys(patentArr) } const onChildSelectChange = (record: any, selected: any, selectedRows: any) => { //record:當(dāng)前操作行 //selected選中狀態(tài) //selectedRows:選擇的數(shù)組 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的長(zhǎng)度是否為data中child的長(zhǎng)度,相等,就將父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:改變的所有數(shù)組 //第一步:判斷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對(duì)應(yīng)的父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)動(dòng)操作就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Vue-Cli如何在index.html中進(jìn)行環(huán)境判斷
這篇文章主要介紹了Vue-Cli如何在index.html中進(jìn)行環(huán)境判斷問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03vant 時(shí)間選擇器--開(kāi)始時(shí)間和結(jié)束時(shí)間實(shí)例
這篇文章主要介紹了vant 時(shí)間選擇器--開(kāi)始時(shí)間和結(jié)束時(shí)間實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-11-11Vue3?<script?setup?lang=“ts“>?的基本使用
<script setup>?是在單文件組件 (SFC) 中使用?composition api?的編譯時(shí)語(yǔ)法糖,本文主要講解<script setup>?與?TypeScript?的基本使用,感興趣的朋友跟隨小編一起看看吧2022-12-12vue項(xiàng)目打包并部署到Linux服務(wù)器的詳細(xì)過(guò)程
我們?cè)跁?huì)開(kāi)發(fā)項(xiàng)目的同時(shí),也應(yīng)該了解一下項(xiàng)目是如何部署到服務(wù)器的,下面這篇文章主要給大家介紹了關(guān)于vue項(xiàng)目打包并部署到Linux服務(wù)器的相關(guān)資料,需要的朋友可以參考下2023-01-01vue終極性能優(yōu)化方案(解決首頁(yè)加載慢問(wèn)題)
最近在做項(xiàng)目中前端采用Vue技術(shù),發(fā)現(xiàn)首頁(yè)加載速度非常之慢,下面這篇文章主要給大家介紹了關(guān)于vue終極性能優(yōu)化方案,主要解決首頁(yè)加載慢問(wèn)題,需要的朋友可以參考下2022-02-02