Ant Design Vue,<a-tabel>进行纵向数据的动态合并

写了一些方法让相同数据的行进行上下合并,可能不是最优解,仅提供一个解决思路,渣代码,望谅解
最终效果:
上效果
思路就是,传入数据源,表头,需要合并的项,然后计算这一行向下有多少个相同的数据就合并多少个单元格,并且被合并的单元格需要obj.attrs.rowSpan = 0

因为需要合并的项是不确定的,我创建了一个对象obj[dataIndex]去记录一些需要用到的变量

引入这个组件:传入的参数有三个 columns表头 dataSource数据源 customRenderList 需要合并的项,其中前两项和ant vue官网demo格式一样,customRenderList传 String[]
在这里插入图片描述
直接把文件放出来

Extable.vue

<template>
  <a-table
    bordered
    class="micTable"
    size="small"
    :loading="loading"
    :columns="columnsList"
    :dataSource="dataSource"
    :pagination="false"
    :scroll="{ x: true }"
  >
  </a-table>
</template>

<script>
/**
 * @param idx         Number   下标名
 * @param dataIndex   String   列名
 * @param arr         Object[] 数据源
 */
function cumputdRowSpan(idx, dataIndex, arr) {
  let firstIdx = idx; //原下标
  let index = idx; //递增下标
  let number = 0;
  do {
    number += 1;
    index += 1;
  } while (!!arr[index] && arr[index][dataIndex] === arr[firstIdx][dataIndex]); //当不存在下一个元素或者已经与当前数据不相同不能进行合并时跳出循环
  return number;//返回需要向下合并的数量
}

export default {
  name: "list",
  props: {
    columns: {
      //表头
      type: Array,
      default: () => [],
    },
    dataSource: {
      //数据源
      type: Array,
      default: () => [],
    },
    customRenderList: {
      //需合并项
      type: Array,
      default: () => [],
    },
    loading: {
      //loading状态
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {};
  },
  computed: {
    columnsList: function () {
      //计算需要进行合并的表头,对符合customRenderList数组元素的属性添加customRender进行合并计算
      let filderList = this.customRenderList;
      return this.columns.map((ele) => {
        return {
          ...ele,
          customRender: filderList.includes(ele.dataIndex) //当识别到这一项是需要进行合并的项时,传入customRender方法
            ? this.renderContent(ele.dataIndex)
            : null,
        };
      });
    },
    customGoal: function () {
      //设置一个obj对象动态存储需要静态记录的属性,每一个dataIndex独立一个动态的记忆区域
      let obj = {};
      this.customRenderList.forEach((key) => {
        obj[key] = {
          value: null,
          index: null,
          rowSpanNunber: null,
        };
      });
      return obj;
    },
  },
  methods: {
    renderContent(name) {
      //动态计算函数,根据传入的dataIndex唯一标识进行计算
      let dataIndex = name;
      //存储this,不会修改this指向
      let that = this;
      return (value, row, index) => {
        //官方例子
        const obj = {
          children: value,
          attrs: {},
        };
        let interspace = this.customGoal[dataIndex];
        if (value !== interspace.value) {
          //当前value如果和空间内存放的value不相同时,则不继续向下合并单元格,重置当前计算空间,并计算需要向下合并多少单元格
          //传入参数计算需要向下合并多少个单元格
          let number = cumputdRowSpan(index, dataIndex, that.dataSource);
          interspace["value"] = value;
          interspace["index"] = index;
          interspace["rowSpanNunber"] = number;
          obj.attrs.rowSpan = number;
        } else {
          //当value与计算空间value相同时则认为当前单元格需要被隐藏 obj.attrs.rowSpan = 0;
          obj.attrs.rowSpan = 0;
        }
        return obj;
      };
    },
  },
};
</script>

<style scoped>
.micTable >>> .ant-table td {
  white-space: nowrap;
}
.micTable >>> .ant-table th {
  white-space: nowrap;
}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值