返回

妙用el-table动态合并单元格:探索span-method的奥秘

前端

灵活自如,巧用 span-method 实现动态合并单元格

在前端开发中,表格是一个必不可少的展示组件,而动态合并单元格更是锦上添花,让表格数据更加清晰美观。在 Vue + Element-UI 中,el-table 提供了强大的动态合并单元格功能,通过 span-method 即可轻松实现。

span-method 的妙用

span-method 接受一个函数作为参数,该函数返回一个包含 rowspan 和 colspan 两个属性的对象。rowspan 表示要合并的行数,colspan 表示要合并的列数。通过设置 span-method,我们可以轻松地将相邻单元格合并成一个单元格。

代码示例:

<el-table :data="tableData">
  <el-table-column prop="name" label="姓名" width="120"></el-table-column>
  <el-table-column prop="age" label="年龄" width="120"></el-table-column>
  <el-table-column prop="gender" label="性别" width="120">
    <template slot-scope="scope">
      <span>{{ scope.row.gender }}</span>
      <span v-if="scope.row.gender === '男'" :colspan="2"></span>
      <span v-else :colspan="2"></span>
    </template>
  </el-table-column>
</el-table>

在这个例子中,我们根据性别动态合并了相邻的两个单元格。如果性别为“男”,则合并为两列,显示“男”;如果性别为“女”,则合并为两列,显示“女”。

应对无序数据的挑战

然而,当后端返回的数据不统一、非按类别排序时,官方的例子就显得捉襟见肘了。因为官方的例子基于数据已经按类别排序的前提下进行合并单元格,而在实际中,后端返回的数据往往是无序的,甚至可能存在缺失或重复的情况。

从数据中寻找规律

为了解决这个问题,我们需要从数据中寻找规律。我们可以通过遍历表格数据,比较前后两个元素是否相等,来构造一个 spanArr 用于存放 rowspan。

具体实现步骤:

  1. 初始化一个空数组 spanArr,用来存放 rowspan。
  2. 遍历表格数据,比较前后两个元素是否相等。
  3. 如果前后两个元素相等,则将当前元素的 rowspan 加 1。
  4. 如果前后两个元素不相等,则将当前元素的 rowspan 置为 1,并将当前元素添加到 spanArr 中。
  5. 将 spanArr 作为 span-method 函数的返回值。

代码示例:

const spanArr = [];
let currentRowspan = 1;
for (let i = 1; i < tableData.length; i++) {
  if (tableData[i].name === tableData[i - 1].name) {
    currentRowspan++;
  } else {
    spanArr.push({
      rowspan: currentRowspan,
      colspan: 1,
    });
    currentRowspan = 1;
  }
}
if (currentRowspan > 1) {
  spanArr.push({
    rowspan: currentRowspan,
    colspan: 1,
  });
}

尽享动态合并单元格的魅力

通过这种方式,我们就可以实现灵活自如的动态合并单元格了。无论后端返回的数据如何无序,我们都可以通过遍历数据来构造出正确的 spanArr,从而实现动态合并单元格。

使用技巧:

  1. 尽量避免合并过多单元格,否则会导致表格难以阅读。
  2. 不要合并包含不同类型数据的单元格,否则会导致数据混乱。
  3. 合并单元格时,要考虑到数据的变化情况,以免出现数据错乱的情况。

常见的疑问

1. 如何同时合并行和列?

span-method({ row, column, rowIndex, columnIndex }) {
  if (row.name === row[rowIndex - 1].name && column.age === column[columnIndex - 1].age) {
    return {
      rowspan: 2,
      colspan: 2,
    };
  }
  return {
    rowspan: 1,
    colspan: 1,
  };
}

2. 如何动态合并不同列的单元格?

span-method({ row, column, rowIndex, columnIndex }) {
  if (row.name === row[rowIndex - 1].name) {
    return {
      rowspan: 2,
      colspan: columnIndex - rowIndex + 1,
    };
  }
  return {
    rowspan: 1,
    colspan: 1,
  };
}

3. 如何根据条件合并单元格?

span-method({ row, column, rowIndex, columnIndex }) {
  if (row.name === row[rowIndex - 1].name && row.age === row[rowIndex - 1].age) {
    return {
      rowspan: 2,
      colspan: 1,
    };
  }
  return {
    rowspan: 1,
    colspan: 1,
  };
}

4. 如何避免重复合并单元格?

let merged = false;
span-method({ row, column, rowIndex, columnIndex }) {
  if (!merged && row.name === row[rowIndex - 1].name) {
    merged = true;
    return {
      rowspan: 2,
      colspan: 1,
    };
  }
  return {
    rowspan: 1,
    colspan: 1,
  };
}

5. 如何在动态合并单元格的基础上添加自定义样式?

.el-table__cell--merged {
  background-color: #f5f5f5;
  border-right: 1px solid #e6e6e6;
  border-bottom: 1px solid #e6e6e6;
}