ant vue table表格数据动态合并

antd 表格动态行合并

合并效果

ant vue table表格数据动态合并_第1张图片

步骤方法

1.在computed节点下动态计算每次要合并的行数

  computed: {
    columns() {
      return [
        {
          title: "区域",
          dataIndex: "area",
          customRender: (text, row, index) => {
            const obj = {
              children: text !== null ? text : "",
              attrs: {
                rowSpan: 1,
              },
            };
            obj.attrs.rowSpan = this.renderCells(text, this.currentTable, "area",index);
            return obj;
          },
        },
        {
          title: "名称",
          dataIndex: "name",
        },
        {
          title: "数量",
          dataIndex: "count",
        },
        {
          title: "进度",
          dataIndex: "progress",
        },
      ];
    },
  }

2.在methods节点下定义合并单元格的方法

renderCells(text, data, key, index) {
      if (data.length < 1) {
        return 1;
      }
      if (text === "" || text === null) {
        data[index].rowNum = 1;
        return 1;
      }
      // 上一行该列数据是否一样
      if (index !== 0 && text === data[index - 1][key] && index % this.pagination.pageSize != 0) {
        data[index].rowNum = 0;
        return 0;
      }
      let rowSpan = 1;
      // 判断下一行是否相等
      for (let i = index + 1; i < data.length; i++) {
        if (text !== data[i][key]) {
          break;
        }
        rowSpan++;
      }
      data[index].rowNum = rowSpan;
      return rowSpan;
    }

3.如果是一次性获取所有数据进行分页的话,计算columns的时候需要进行修改一下

    columns() {
      return [
        {
          title: "区域",
          dataIndex: "area",
          customRender: (text, row, index) => {
            const obj = {
              children: text !== null ? text : "",
              attrs: {
                rowSpan: 1,
              },
            };
            obj.attrs.rowSpan = this.renderCells(text, this.currentTable, "area", Number(index)+Number(this.pagination.pageSize * (this.pagination.current - 1)));
            return obj;
          },
        },
        {
          title: "名称",
          dataIndex: "name",
        },
        {
          title: "数量",
          dataIndex: "count",
        },
        {
          title: "进度",
          dataIndex: "progress",
        },
      ];
    },

参考文章:ant design vue 动态表格合并

合并效果

如果我们想要实现名称列相同的进行合并,需要在原来的代码上进行修改。合并的前提是区域相同,并且名称相同的情况下我们才进行合并,只需要在计算合并行数的时候需要加一层判断即可。
ant vue table表格数据动态合并_第2张图片

    renderCells(text, data, key, index) {
      if (data.length < 1) {
        return 1;
      }
      if (text === "" || text === null) {
        data[index].rowNum = 1;
        return 1;
      }
      // 上一行该列数据是否一样
      if (index !== 0 && text === data[index - 1][key] && index % this.pagination.pageSize != 0) {
        if(key === 'name'){
          if(data[index-1]['area'] === data[index]['area']){
            data[index].rowNum = 0
            return 0;
          }
        }else{
          data[index].rowNum = 0;
          return 0;
        }

      }
      let rowSpan = 1;
      // 判断下一行是否相等
      for (let i = index + 1; i < data.length; i++) {
        if(key === 'name' && data[i]['area'] !== data[index]['area']){
          break;
        }
        if (text !== data[i][key] ) {
          break;
        }
        rowSpan++;
      }
      data[index].rowNum = rowSpan;
      return rowSpan;
    },

单元格可编辑

非合并的行

可以参考官方的ant-design-vue可编辑单元格,官方示例如下:

<template>
  <div>
    <a-button class="editable-add-btn" @click="handleAdd">
      Add
    </a-button>
    <a-table bordered :data-source="dataSource" :columns="columns">
      <template slot="name" slot-scope="text, record">
        <editable-cell :text="text" @change="onCellChange(record.key, 'name', $event)" />
      </template>
      <template slot="operation" slot-scope="text, record">
        <a-popconfirm
          v-if="dataSource.length"
          title="Sure to delete?"
          @confirm="() => onDelete(record.key)"
        >
          <a href="javascript:;">Delete</a>
        </a-popconfirm>
      </template>
    </a-table>
  </div>
</template>
<script>
const EditableCell = {
  template: `
      
{{ value || ' ' }}
`
, props: { text: String, }, data() { return { value: this.text, editable: false, }; }, methods: { handleChange(e) { const value = e.target.value; this.value = value; }, check() { this.editable = false; this.$emit('change', this.value); }, edit() { this.editable = true; }, }, }; export default { components: { EditableCell, }, data() { return { dataSource: [ { key: '0', name: 'Edward King 0', age: '32', address: 'London, Park Lane no. 0', }, { key: '1', name: 'Edward King 1', age: '32', address: 'London, Park Lane no. 1', }, ], count: 2, columns: [ { title: 'name', dataIndex: 'name', width: '30%', scopedSlots: { customRender: 'name' }, }, { title: 'age', dataIndex: 'age', }, { title: 'address', dataIndex: 'address', }, { title: 'operation', dataIndex: 'operation', scopedSlots: { customRender: 'operation' }, }, ], }; }, methods: { onCellChange(key, dataIndex, value) { const dataSource = [...this.dataSource]; const target = dataSource.find(item => item.key === key); if (target) { target[dataIndex] = value; this.dataSource = dataSource; } }, onDelete(key) { const dataSource = [...this.dataSource]; this.dataSource = dataSource.filter(item => item.key !== key); }, handleAdd() { const { count, dataSource } = this; const newData = { key: count, name: `Edward King ${count}`, age: 32, address: `London, Park Lane no. ${count}`, }; this.dataSource = [...dataSource, newData]; this.count = count + 1; }, }, }; </script>

ant vue table表格数据动态合并_第3张图片

动态合并可编辑单元格

实际运用过程中,可能会遇到需要动态合并可编辑的单元格,已知scopedSlots可以帮助我们实现编辑单元格,customRender中可以自定义动态合并单元格。但是经过实践发现这两者无法同时使用。参考ant-design-vue表格动态合并可编辑单元格的解决方法发现可以通过JSX语法来解决scopedSlots和customRender冲突的问题

  computed: {
    columns() {
      return [
        {
          title: "区域",
          dataIndex: "area",
          scopedSlots: { customRender: 'area' },
          customRender: (text, row, index) => {
            const obj = {
              children: <editable-cell text={text} onChange={(val) => this.onCellChange(row.id,'area',val)}></editable-cell>,
              attrs: {
                rowSpan: 1,
              },
            };
            obj.attrs.rowSpan = this.mergeCells(text, this.currentTable, "area", Number(index)+Number(this.pagination.pageSize * (this.pagination.current - 1)));
            return obj;
          },
        },
        {
          title: "名称",
          dataIndex: "name",
         
        },
        {
          title: "数量",
          dataIndex: "count",
        },
        {
          title: "进度",
          dataIndex: "progress",
        },
      ];
    },
  },
实现效果

ant vue table表格数据动态合并_第4张图片

你可能感兴趣的:(VUE,vue.js,javascript,前端)