首先看需求 使用antd 实现这样一个表格 合并单元格
原理:
-
翻阅资料 看官网效果
// 只看合并单元格的原理
const columns = [
{
title: 'Home phone',
colSpan: 2,
dataIndex: 'tel',
render: (value, row, index) => {
const obj = {
children: value,
props: {},
};
if (index === 2) {
obj.props.rowSpan = 2; // 当index等于2的时候 表示第3行,rowSpan等于2表示占据2行
}
if (index === 3) {
obj.props.rowSpan = 0; // 当index等于3的时候 表示第4行,rowSpan等于0表示不渲染,上面那行已把它合并了
}
return obj;
},
}
];
// 比如我要合并三行 我第一行 就写3 下面两行不渲染就写0
if (index === 0) {
obj.props.rowSpan = 3;
}
if (index === 1) {
obj.props.rowSpan = 0;
}
if (index === 2) {
obj.props.rowSpan = 0;
}
-
得出结论:
看需求:虽然看起来只有3大行,其实这里需要有9条数据,然后日期与日期折扣合并了而已
- 看后端返回的数据
const responseData = [
{
dateDiscount: 1,
endDate: "2019-01-02",
startDate: "2019-01-01",
timeData:[
{
discountPrice: 1,
endTime: "21:21:21",
startTime: "20:20:20",
timeDiscount: 1,
},
{
discountPrice: 2,
endTime: "21:21:21",
startTime: "20:20:20",
timeDiscount: 2,
},
{
discountPrice: 3,
endTime: "21:21:21",
startTime: "20:20:20",
timeDiscount: 3,
}
]
},
{
dateDiscount: 1,
endDate: "1111-11-11", // 1111-11-11的时候 展示 其他日期
startDate: "1111-11-11",
timeData:[
{
discountPrice: 0.012,
endTime: "00:00:00",
startTime: "00:00:00",
timeDiscount: 2,
},
{
discountPrice: 0.013,
endTime: "00:00:00",
startTime: "00:00:00",
timeDiscount: 3,
}
]
}
]
- 操作数据
// 两次循环 将2大条数据改成 5条数据
// 然后把这5条数据各自的rowSpan计算出来放入对象
responseData.map(responseDataItem=>{
const len = responseDataItem.timeData.length;
responseDataItem.timeData.map((timeDataItem,index)=>{
arr = [
...arr,
{
time:timeDataItem.startTime+'-'+timeDataItem.endTime,
discountPrice: timeDataItem.discountPrice,
timeDiscount: timeDataItem.timeDiscount,
date:responseDataItem.startDate === '1111-11-11' ? '其他日期' : responseDataItem.startDate+'-'+responseDataItem.endDate,
dateDiscount:responseDataItem.dateDiscount,
span:index === 0 ? len : 0 // 各自的rowSpan计算出来放入对象
}
]
return arr
})
return arr
})
const tableData = arr.map((item, index) => {
item.key = index;
return item;
})
- 得出数据格式:
const tableData = [
{
key:0,
date:'1111',
dateDiscount:'0.1',
createTime:'1111-22222',
timeDiscount:'0.222',
discountPrice:'1111',
span:2, // 合并占据2行
},
{
key:1,
date:'222',
dateDiscount:'0.1',
createTime:'55555-66666',
timeDiscount:'0.3333',
discountPrice:'2222',
span:0, // 被合并 不渲染
},
{
key:2,
date:'3333',
dateDiscount:'0.1',
createTime:'77777-88888',
timeDiscount:'0.4444',
discountPrice:'3333',
span:4, // 合并占据4行
},
{
key:3,
date:'444444',
dateDiscount:'0.1',
createTime:'77777-88888',
timeDiscount:'0.4444',
discountPrice:'3333',
span:0, // 被合并 不渲染
},
{
key:4,
date:'55555',
dateDiscount:'0.1',
createTime:'77777-88888',
timeDiscount:'0.4444',
discountPrice:'3333',
span:0, // 被合并 不渲染
},
{
key:5,
date:'66666',
dateDiscount:'0.1',
createTime:'77777-88888',
timeDiscount:'0.4444',
discountPrice:'3333',
span:0, // 被合并 不渲染
}
]
//最后 放入antd table
setTableColumns([
{
title: '日期',
dataIndex: 'date',
key: 'date',
width: 140,
render: (value, row, index) => { // 渲染tableData每一行的数据 设置各自的rowSpan
return {
children: value,
props: {rowSpan:row.span},
};
},
},
{
title: '日期折扣',
dataIndex: 'dateDiscount',
key: 'dateDiscount',
width: 140,
render: (value, row) => {
return {
children: value,
props: {rowSpan:row.span},
};
},
},
{
title: '时间',
dataIndex: 'createTime',
key: 'createTime',
width: 140
},
{
title: '时间折扣',
dataIndex: 'timeDiscount',
key: 'timeDiscount',
width: 140
},
{
title: '价格(元)',
dataIndex: 'discountPrice',
key: 'discountPrice',
width: 140
}
])
<Table columns={tableColumns} dataSource={tableData} bordered />
-
最后效果
完整代码
import React, { useState, useEffect,useCallback } from 'react';
import './index.less';
import { Modal, Table } from 'antd';
import moment from 'moment';
import { config_discount_list } from '../../../services/api';
function DiscountsDetailModal(props) {
const [tableData, setTableData] = useState([]); // list数据
const [visible,setVisible ] = useState(false);
const [tableColumns,setTableColumns] = useState([]);
const [filterParams, setFilterParams] = useState({}); // 查询表单的参数
// const [updateList, setUpdateList] = useState([]); // 回显
const [serveConfigId, setServeConfigId] = useState(); // 是否修改状态
// const format = 'HH:mm';
// const dateFormat = 'YYYY/MM/DD';
// 后端返回的数据
// [
// {
// dateDiscount: 1,
// endDate: "2019-01-02",
// startDate: "2019-01-01",
// timeData:[
// {
// discountPrice: 1,
// endTime: "21:21:21",
// startTime: "20:20:20",
// timeDiscount: 1,
// },
// {
// discountPrice: 2,
// endTime: "21:21:21",
// startTime: "20:20:20",
// timeDiscount: 2,
// },
// {
// discountPrice: 3,
// endTime: "21:21:21",
// startTime: "20:20:20",
// timeDiscount: 3,
// }
// ]
// },
// {
// dateDiscount: 1,
// endDate: "1111-11-11",
// startDate: "1111-11-11",
// timeData:[
// {
// discountPrice: 0.012,
// endTime: "00:00:00",
// startTime: "00:00:00",
// timeDiscount: 2,
// },
// {
// discountPrice: 0.013,
// endTime: "00:00:00",
// startTime: "00:00:00",
// timeDiscount: 3,
// }
// ]
// }
// ]
// 我操作以后得出的数据
// [
// {
// key:0,
// date:'1111',
// dateDiscount:'0.1',
// createTime:'1111-22222',
// timeDiscount:'0.222',
// discountPrice:'1111',
// span:2,
// },
// {
// key:1,
// date:'222',
// dateDiscount:'0.1',
// createTime:'55555-66666',
// timeDiscount:'0.3333',
// discountPrice:'2222',
// span:0,
// },
// {
// key:2,
// date:'3333',
// dateDiscount:'0.1',
// createTime:'77777-88888',
// timeDiscount:'0.4444',
// discountPrice:'3333',
// span:4,
// },
// {
// key:3,
// date:'444444',
// dateDiscount:'0.1',
// createTime:'77777-88888',
// timeDiscount:'0.4444',
// discountPrice:'3333',
// span:0,
// },
// {
// key:4,
// date:'55555',
// dateDiscount:'0.1',
// createTime:'77777-88888',
// timeDiscount:'0.4444',
// discountPrice:'3333',
// span:0,
// },
// {
// key:5,
// date:'66666',
// dateDiscount:'0.1',
// createTime:'77777-88888',
// timeDiscount:'0.4444',
// discountPrice:'3333',
// span:0,
// }
// ]
const requestList = useCallback(async () => {
let res = await config_discount_list({ serveConfigId});
if (res.data.responseCode) return
let responseData = res.data.responseData;
setVisible(true)
let arr = [];
responseData.map(responseDataItem=>{
const len = responseDataItem.timeData.length;
responseDataItem.timeData.map((timeDataItem,index)=>{
arr = [
...arr,
{
time:timeDataItem.startTime+'-'+timeDataItem.endTime,
discountPrice: timeDataItem.discountPrice,
timeDiscount: timeDataItem.timeDiscount,
date:responseDataItem.startDate === '1111-11-11' ? '其他日期' : responseDataItem.startDate+'-'+responseDataItem.endDate,
dateDiscount:responseDataItem.dateDiscount,
span:index === 0 ? len : 0
}
]
return arr
})
return arr
})
const tableData = arr.map((item, index) => {
item.key = index;
return item;
})
setTableData(tableData);
})
useEffect(()=>{
setVisible(props.visible);
setServeConfigId(props.serveConfigId);
}, [props.visible, props.serveConfigId])
useEffect(()=>{
if(serveConfigId && serveConfigId !== -1){
requestList()
}
}, [serveConfigId])
useEffect(()=>{
setTableColumns([
{
title: '日期',
dataIndex: 'date',
key: 'date',
width: 140,
render: (value, row, index) => {
return {
children: value,
props: {rowSpan:row.span},
};
},
},
{
title: '日期折扣',
dataIndex: 'dateDiscount',
key: 'dateDiscount',
width: 140,
render: (value, row) => {
return {
children: value,
props: {rowSpan:row.span},
};
},
},
{
title: '时间',
dataIndex: 'createTime',
key: 'createTime',
width: 140
},
{
title: '时间折扣',
dataIndex: 'timeDiscount',
key: 'timeDiscount',
width: 140
},
{
title: '价格(元)',
dataIndex: 'discountPrice',
key: 'discountPrice',
width: 140
}
])
}, [])
const onCancel = () => {
setVisible(false)
props.close(false)
}
return (
<Modal
destroyOnClose={true}
className="discountsDetailModal"
title="优惠详情"
centered
visible={ visible }
onCancel={ onCancel }
okText="确定"
cancelText="取消"
maskClosable={ false }
width={600}
>
<Table columns={tableColumns} dataSource={tableData} bordered />
</Modal>
)
}
export default DiscountsDetailModal;