Vben admin - 表格组件合并单元格

需求

最近在项目中有需求需要表格合并单元格,不但内容有合并的,操作列也需要合并,找遍vben官方例子,没有实现操作列合并的,只能硬着头皮实现,还好实现了,下面具体就是实现思路;

原型设计图

在这里插入图片描述

分析需求

整体思路就是当数据中一级分类值相同则进行合并分数、一级分类以及编辑分数(操作列),由于操作列合并vben框架目前不支持,只能在数据上下功夫,假设表格数据中每组数据返回字段operatorName:‘操作’;这样我们就像渲染普通数据一样渲染出来,然后再给器操作加上事件即可

合并核心思路
let newArr = data.reduce((result, item) => {
     // 首先将字段作为新数组result取出
     if (result.indexOf(item['name']) < 0) {
       result.push(item['name']);
     }
     return result;
   }, []).reduce((res, name) => {
     // 将name相同的数据作为新数组取出,并在其内部添加新字段**rowSpan**
     const children = data.filter((item) => item['name'] === name);
     // eslint-disable-next-line no-param-reassign
     res = res.concat(
       children.map((item, index) => ({
         ...item,
         ['rowspan']: index === 0 ? children.length : 0, // 将第一行数据添加rowSpan字段
       })),
     );
     return res;
   }, []);
整体代码
const [registerTable] = useTable({
  title: '合并单元格',
  bordered: true,
  // 假数据
  dataSource: [
    {
      key: '1',
      fenshu: 5,
      name: '政治',
      age: '政治交流',
      num: 4545,
      address: 'New York No. 1 Lake Park',
      rowspan:2
    },
    {
      key: '2',
      fenshu: 5,
      name: '政治',
      age: '总统选举',
      num: 4545,
      address: 'London No. 1 Lake Park',
      rowspan:0
    },
    {
      key: '3',
      fenshu: 5,
      name: '经济',
      age: '黄金大涨',
      num: 4545,
      address: 'Sidney No. 1 Lake Park',
      rowspan:1
    },
    {
      key: '4',
      fenshu: 5,
      name: '军事',
      age: '核弹引爆',
      num: 4545,
      address: 'London No. 2 Lake Park',
      rowspan:1
    },
    {
      key: '5',
      fenshu: 5,
      name: '安全',
      age: '食品安全',
      num: 4545,
      address: 'Dublin No. 2 Lake Park',
      rowspan:1
    },
  ],
   afterFetch: (data) => {
      let newArr = data
        .reduce((result, item) => {
          // 首先将字段作为新数组result取出
          if (result.indexOf(item['name']) < 0) {
            result.push(item['name']);
          }
          return result;
        }, [])
        .reduce((res, name) => {
          // 将name相同的数据作为新数组取出,并在其内部添加新字段**rowSpan**
          const children = data.filter((item) => item['name'] === name);
          // eslint-disable-next-line no-param-reassign
          res = res.concat(
            children.map((item, index) => ({
              ...item,
              ['rowspan']: index === 0 ? children.length : 0, // 将第一行数据添加rowSpan字段
            })),
          );
          return res;
        }, []);
      return newArr;
    },
  columns: [
  {
    title: '分数',
    dataIndex: 'fenshu',
    width: 200,
    customRender: ({ text, record }) => {
      const obj = {
        children: text,
        props: {} as any,
      };
      obj.props.rowSpan = record.rowspan;
      return obj;
    },
  },
  {
    title: '一级分类',
    dataIndex: 'name',
    customRender: ({ text, record }) => {
      const obj = {
        children: text,
        props: {} as any,
      };
      obj.props.rowSpan = record.rowspan;
      return obj;
    },
  },
  {
    title: '二级分类',
    dataIndex: 'age',
    width: 180,
  },
  {
    title: '内容',
    dataIndex: 'address',
    width: 380,
  },
  {
    title: '数据来源数量',
    dataIndex: 'num',
    width: 180,
  },
  {
      title: '操作',
      dataIndex: 'operatorName',
      width: 180,
      customRender: ({ text, record }) => {
        return {
          children: h('a', { onClick: () => handelEdit(record) }, text),
          props: {
            rowSpan: record.rowspan,
          },
        };
      },
      className: 'caozuo', // 单独加上样式类名,在css中将字体颜色改为蓝色 以便和普通数据进行区分
    },
],
  pagination: false,
  showIndexColumn: false,
})

// 编辑操作
const handelEdit = (record: Recordable) => {
 console.log(record)
};
最后实现效果图

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值