React使用antd对于复杂数据类型表的渲染
数据
const table = [
{
firstType: '电器',
results: [
{
secondType: '电视',
list: [
{
name: '小米',
number: 20,
price: 800
},
{
name: '长虹',
number: 10,
price: 500
}
]
},
{
secondType: '冰箱',
list: [
{
name: '美的',
number: 20,
price: 1000
},
{
name: '海尔',
number: 10,
price: 888
}
]
}
]
},
{
firstType: '食物',
results: [
{
secondType: '零食',
list: [
{
name: '坚果',
number: 50,
price: 8
},
{
name: '辣条',
number: 80,
price: 3
}
]
},
{
secondType: '生疏',
list: [
{
name: '青菜',
number: 100,
price: 1
}
]
}
]
}
]
方法1:表格行列合并
思路:将复杂的嵌套数据转换一条条的各自独立的数据,当其有相同的元素 对其合并
import React, { useState, useEffect } from 'react'
import { Table } from 'antd'
const spanTable = () => {
const [tableData, setTableData] = useState<any[]>([])
const getTableData = () => {
const table = [
{
firstType: '电器',
results: [
{
secondType: '电视',
list: [
{
name: '小米',
number: 20,
price: 800
},
{
name: '长虹',
number: 10,
price: 500
}
]
},
{
secondType: '冰箱',
list: [
{
name: '美的',
number: 20,
price: 1000
},
{
name: '海尔',
number: 10,
price: 888
}
]
}
]
},
{
firstType: '食物',
results: [
{
secondType: '零食',
list: [
{
name: '坚果',
number: 50,
price: 8
},
{
name: '辣条',
number: 80,
price: 3
}
]
},
{
secondType: '生疏',
list: [
{
name: '青菜',
number: 100,
price: 1
}
]
}
]
}
]
setTableData(handleSpan(table))
}
// 表格合并方法
const handleSpan = (table, type = 3) => {
const newData: any[] = []
// 合并
// 处理合并表格数据
table.map((item, i) => {
if (item.results && item.results.length) {
item.results.map((ss, si) => {
if (ss.list && ss.list.length) {
ss.list.map((tt, ti) =>{
const newItem = {
index: i + 1,
id: Math.floor(Math.random() * 100),//可以引入 nanoid组件生成不重复的id
firstType: item.firstType,
secondType: ss.secondType,
...tt
}
// 三级合并的行数,所有子级results的长度
if (si === 0 && ti === 0) {
newItem.oneRowSpan = item.results.reduce((a, b) => {
// console.log(a, b)
return a + b.list.length
}, 0)
}
// 二级合并的行,当前子级list的长度
if (ti === 0) {
newItem.twoRowSpan = ss.list.length
}
newData.push(newItem)
})
}
})
}
})
console.log(newData)
return newData
}
useEffect(() => {
getTableData()
}, [])
const colums = [
{
title: '排序',
dataIndex: 'index',
render: (value, row) => {
const obj = {
children: value,
props: {
rowSpan: 0
},
};
// 三级合并
if (row.oneRowSpan) {
obj.props.rowSpan = row.oneRowSpan;
}
return obj;
},
},
{
title: '一级分类',
dataIndex: 'firstType',
render: (value, row) => {
const obj = {
children: value,
props: {
rowSpan: 0
},
};
// 三级合并
if (row.oneRowSpan) {
obj.props.rowSpan = row.oneRowSpan;
}
return obj;
},
},
{
title: '二级分类',
dataIndex: 'secondType',
render: (value, row) => {
const obj = {
children: value,
props: {
rowSpan: 0
},
};
// 二级合并
if (row.twoRowSpan) {
obj.props.rowSpan = row.twoRowSpan;
}
return obj;
},
},
{
title: '名称',
dataIndex: 'name',
},
{
title: '数量',
dataIndex: 'number',
},
{
title: '价格',
dataIndex: 'price',
},
]
return (
<div>
<h3 style={{marginTop: '15px'}}>表格合并</h3>
<Table
bordered
columns={colums}
rowKey="id"
dataSource={tableData}
pagination={false}
/>
</div>
)
}
export default spanTable
缺点:当负载类型数据量很大时 不便对于数据进行分析
方法二:使用嵌套子表格对于数据渲染
代码:
-
可以运用方法一的方法,将数据类型修改成如下处理:
const table: any =[ { firstType: '电器', secondType: '电视', results: [ { name: '小米', number: 20, price: 800 }, { name: '长虹', number: 10, price: 500 } ] }, { firstType: '电器', secondType: '冰箱', results: [ { name: '美的', number: 20, price: 1000 }, { name: '海尔', number: 10, price: 888 }, ] }, { firstType: '食物', secondType: '零食', results: [ { name: '坚果', number: 50, prie: 8 }, { name: '辣条', number: 80, price: 3 } ] }, { firstType: '食物', secondType: '生疏', results: [ { name: '青菜', number: 100, price: 1 } ] }, ]
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 table: any =[
{
firstType: '电器',
secondType: '电视',
results: [
{
name: '小米',
number: 20,
price: 800
},
{
name: '长虹',
number: 10,
price: 500
}
]
},
{
firstType: '电器',
secondType: '冰箱',
results: [
{
name: '美的',
number: 20,
price: 1000
},
{
name: '海尔',
number: 10,
price: 888
},
]
},
{
firstType: '食物',
secondType: '零食',
results: [
{
name: '坚果',
number: 50,
prie: 8
},
{
name: '辣条',
number: 80,
price: 3
}
]
},
{
firstType: '食物',
secondType: '生疏',
results: [
{
name: '青菜',
number: 100,
price: 1
}
]
},
]
const parentColumns: any = [
{
title: '第一类',
dataIndex: 'firstType',
key: 'firstType',
},
{
title: '第二类',
dataIndex: 'secondType',
key: 'secondType',
},
]
const expandedRowRender = (record: any, index: any, indent: any, expanded: any) => {
const childData = record.results
const childColumns: any = [
{
title: <span style={{ color: "green" }}>名称</span>,
dataIndex: 'name',
key: 'name'
},
{
title: <span style={{ color: "green" }}>数量</span>,
dataIndex: 'number',
key: 'number'
},
{
title: <span style={{ color: "green" }}>价格</span>,
dataIndex: 'price',
key: 'price'
},
]
return <Table columns={childColumns} dataSource={childData} pagination={false} />
}
return (
<div>
<Table columns={parentColumns} dataSource={table} expandable={{ expandedRowRender }}/>
</div>
);
}
暂时只能理解到这两种方法,但数据量增大的化,还是不够理想