react antd Table动态合并单元格

该博客介绍了如何使用JavaScript处理并合并具有相同`name`字段的对象数组,以创建适合antd Table组件渲染的新数组。通过`createNewArr`函数,将相同`name`的元素合并,添加`rowSpan`属性,并展示如何定义相关列以实现单元格合并。示例代码展示了如何处理`data`数组,将具有相同`type`的元素合并,并在Table组件中展示。
摘要由CSDN通过智能技术生成

原始数组

const data = [
  {
    key: '0',
    name: 'John Brown',
    age:22,
    address: 'New York No. 1 Lake Park',
    tags: ['nice', 'developer'],
  },
  {
    key: '1',
    name: 'John Brown',
    age: 42,
    address: 'London No. 1 Lake Park',
    tags: ['loser'],
  },
  {
    key: '2',
    name: 'John Brown',
    age:22,
    address: 'New York No. 1 Lake Park',
    tags: ['nice', 'developer'],
  },
  {
    key: '5',
    name: 'Joe Black',
    age: 3,
    address: 'Sidney No. 1 Lake Park',
    tags: ['cool', 'teacher'],
  },
  {
    key: '6',
    name: 'Joe Black',
    age: 342,
    address: 'Sidney No. 1 Lake Park',
    tags: ['cool', 'teacher'],
  },
  {
    key: '7',
    name: 'Joe Black',
    age: 62,
    address: 'Sidney No. 1 Lake Park',
    tags: ['cool', 'teacher'],
  },
];

name是本文实例需要合并的字段
数据字段包括keynameageaddresstags等假数据,目的是实现将具有相同name的元素合并为一个数组,然后将这些数组展开成为符合antd Table渲染条件的新数组,如下:
在这里插入图片描述
合并结果如下
在这里插入图片描述
合并单元格解决方案
合并函数

//合并数组单元格
  createNewArr=(data)=>{
    return data.reduce((result, item) => {
    //首先将name字段作为新数组result取出
        if (result.indexOf(item.name) < 0) {
            result.push(item.name)
        }
        return result
    }, []).reduce((result, name) => {
    //将name相同的数据作为新数组取出,并在其内部添加新字段**rowSpan**
      const children = data.filter(item => item.name === name);
      result = result.concat(
        children.map((item, index) => ({
          ...item,
          rowSpan: index === 0 ? children.length : 0,//将第一行数据添加rowSpan字段
        }))
      )
      return result;
    }, [])
  }

使用方法

const columns = [
     {
       title: '分类名称',
       dataIndex: 'name',
       key: 'name',
       render(_, row) {
           return {
             children: row.name,
             props: {
               rowSpan: row.rowSpan,
             }
           }
         }
     },
]

//Table传入数据之前对数据做处理
<Table columns={columns} dataSource={this.createNewArr(data)}/>

实例
在这里插入图片描述

 //合并数组单元格
 const createNewArr=(data)=>{
    return data.reduce((result, item) => {
        result.indexOf(item.type) == -1 && result.push(item.type)
        return result
    }, []).reduce((result, type) => {
    //将type相同的数据作为新数组取出,并在其内部添加新字段**rowSpan**
      const children = data.filter(item => item.type === type);
      result = result.concat(
        children.map((item, index) => ({
          ...item,
          rowSpan: index === 0 ? children.length : 0,//将第一行数据添加rowSpan字段
        }))
      )
      return result;
    }, [])
  }

  const getColumns = () => {
    let columns = [
      {
        title: 'Type',
        dataIndex: 'type',
        key: 'type',
        align: 'center',
        render(_, row) {
            return {
              children: row.type,
              props: {
                rowSpan: row.rowSpan,
              }
            }
          }
      },{
        title: 'Severity',
        dataIndex: 'age',
        key: 'age',
        align: 'center',
        render(text, row) {
          return ( row.address == 'No know drug allergy' || !row.address  ? <span> --</span> : text ? <span>{text}</span> : <span>--</span>)
          }
      },{
        title: 'Update date',
        dataIndex: 'name',
        key: 'name',
        align: 'center',
        render(text, row) {
           return ( text ? <span> {text}</span> : <span> -- </span>)
          }
      },{
          title: 'Allergy/ADR/alert',
          dataIndex: 'address',
          key: 'address',
          align: 'center',
          render(text, row) {
             return (text ? <span> {text}</span> :  <span> --</span>)
            }
        },{
          title: 'FDB',
          dataIndex: 'key',
          key: 'key',
          align: 'center',
          render(text, row) {
             return ( row.address == 'No know drug allergy' || !row.address ? <span> --</span> : text ? <span> Y </span> : <span> N</span>)
            }
        },
    ]
    return columns
  }
    <Table columns={getColumns()} dataSource={createNewArr(data)} bordered pagination={false} />
const data = [
    {
      key: '0',
      name: 'John Brown',
      age: '',
      address: 'New York No. 1 Lake Park',
      type: 'Allergy'
    },
    {
      key: '1',
      name: 'John Brown',
      age: 42,
      address: 'London No. 1 Lake Park',
      type: 'Alert'
    },
    {
      key: '2',
      name: 'John Brown',
      age:22,
      address: '',
      type: 'Allergy'
    },
    {
      key: '5',
      name: '',
      age: 3,
      address: 'Sidney No. 1 Lake Park',
      type: 'ADR'
    },
    {
      key: '6',
      name: 'Joe Black',
      age: 342,
      address: 'No know drug allergy',
      type: 'Allergy'
    },
   {
      key: '8',
      name: 'John Brown',
      age:22,
      address: 'New York No. 1 Lake Park',
      type: 'ADR'
    },  {
      key: '',
      name: 'Joe Black',
      age: 62,
      address: 'Sidney No. 1 Lake Park',
      type: 'Alert'
    },   
  ];

参考
https://www.cnblogs.com/y769062159/p/11940068.html
https://www.cnblogs.com/liumcb/p/13042586.html
https://blog.csdn.net/qq_44213014/article/details/109508346
https://blog.csdn.net/qq_44213014/article/details/109508346

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值