el-table 合并单元格,展示合计行并自定义单元格内容

啰嗦两句

怎么用了这么一个标题呢,是因为我的业务需求就是这样,迫于文笔垃圾且词穷,需求当标题。

业务需求 && 设计原型

业务需求应该不需要说,看设计图,大家应该都很明白啦。那我来简单说一下(唉,皮一下很开心)。表格数据中:

  • 第一列合并相同名称的行,相同名称数据项数量不固定。
  • 添加合计行,合计行名称占据两列单元格,合并居中
  • 合计行最后一个单元格,展示自定义内容,本需求中是进度条
    设计图如下,我把需求对应标上了
    el-table 合并单元格,展示合计行并自定义单元格内容_第1张图片

实现

先回顾element的合并行或列
el-table 合并单元格,展示合计行并自定义单元格内容_第2张图片
很清楚了,绑定一个方法,方法中实现我们的合并行,而我们需求中要合并的行的数量并不固定,所以不能直接复制官网的例子。

  computed: {
    groupNum() {
      // 获取需合并的数据名称
      return new Set(this.data.map((o) => o.name));
    }
  },
  methods: {
      nameGroup(name) {
        // 获取相同名称的长度
        return this.getData.filter((o) => o.name == name).length;
      },
      nameLen(name) {
        const tmp = Array.from(this.groupNum);

        let index = tmp.indexOf(name);
        let len = 0;
        for (let i = 0; i < index; i++) {
          len += this.nameGroup(tmp[i]);
        }
        return len;
      },

      // 合并列
      objectSpanMethod(data) {
        const { row, column, rowIndex, columnIndex } = data;
        if (columnIndex === 0) { 
        // 根据重名的数据长度,计算合并的单元格长度
          const len = this.nameGroup(row.name);
          let lenName = this.nameLen(row.name);
          if (rowIndex === lenName) {
            return {
              rowspan: len, // 根据实际重复的名称合并,而不是像官网例子中写死合并2行
              colspan: 1,
            };
          } else {
            return {
              rowspan: 0,
              colspan: 0,
            };
          }
        }
      }
  }

到这里,就实现我们的需求第一项了。下面就是合计行。惯例,复习下element的合计行
el-table 合并单元格,展示合计行并自定义单元格内容_第3张图片
绑定一个getSummaries方法,用于自定义合计行的数据展示。
需求2:“合计”占据两列,合并并居中,这边参考网上实现,从样式上进行处理。隐藏第二列,让第一列colspan为2并居中。
需求3:最后一个单元格中放置进度条。这边我的考虑是从实际渲染结构中添加元素。考虑到表格存在翻页情况,进度条的值存在变化,所以这块处理放在监听watch中。

watch: {
    // 合计行的合并单元格
    getData: {
      async handler() {
        await this.$nextTick(() => {
          const tds = document.querySelectorAll(
            "#table .el-table__footer-wrapper tr>td"
          );
          tds[0].colSpan = 2;
          tds[0].style.textAlign = "center";
          tds[1].style.display = "none";
        });
      },
      immediate: true,
    },
    sums: {
      async handler() { // 合计行的纠纷转化率
        await this.$nextTick(() => {
          const tds = document.querySelectorAll(
            "#table .el-table__footer-wrapper tr>td .cell"
          );
          tds[4].innerHTML = `
            

${this.sums[4]}%

`; document.getElementById("bar").style.width = this.sums[4] + "%"; }); }, immediate: true, deep: true, }, methods:{ // 合计 getSummaries(param) { const { columns, data } = param; columns.forEach((column, index) => { if (index === 0) { this.sums[index] = "合计"; return; } const values = data.map((item, index) => Number(item[column.property])); if (index === 2 || index === 3) { // 计算评估总量和生成报告数 if (!values.every((value) => isNaN(value))) { this.sums[index] = values.reduce((prev, curr) => { const value = Number(curr); if (!isNaN(value)) { return prev + curr; } else { return prev; } }, 0); } } else if (index === 4) { // 计算纠纷转换率 let num1 = 0, num2 = 0; data.map((item) => { num1 += item.num; num2 += item.report; }); this.sums[4] = (num2 / num1).toFixed(2) * 100; } }); return this.sums; }, }

写完这篇文章以后,我感觉这整块的需求都不是很难,然后实际开发中,我也是琢磨很久,网页开了一个又一个,关键词换了一批又一批。还是过于浮躁,遇到问题,第一反应就是搜索,看看网上有没有现成的代码可以copy,copy完了进行下一个需求或者直接就完成项目了,没有后续的理解与反思。遇到需求,先分析,可以不会写,但是要有思路,再逐一实践。加油,共勉!

你可能感兴趣的