el-table 设置合并行或列时,显示错乱问题

1. 需求效果图:

2. 接口数据格式:

点击查看代码

复制代码
  const list = [
    {
      contractNo: "CAI-20220801001",
      contractItem: "用户质量指数",
      count: 15234,
      customerItems: [
        {
          contractNo: null,
          contractItem: "反欺诈分",
          price: null,
          priceType: null,
          count: 7302,
          amount: null,
        },
        {
          contractNo: null,
          contractItem: "逾期评估分",
          price: null,
          priceType: null,
          count: 8234,
          amount: null,
        },
      ],
    },
    {
      contractNo: "CAI-20220801001",
      contractItem: "价值经营分",
      count: 900,
      customerItems: [
        {
          contractNo: null,
          contractItem: "价值经营分",
          price: null,
          priceType: null,
          count: 15234,
          amount: null,
        },
      ],
    },
  ];

3. 实现过程:

element plus 官网中有描述合并表格行列的方法:点此查看文档

表格部分代码如下:

复制代码
  <el-table
    class="table-box"
    border
    m-t-27px
    :data="tableData"
    style="width: 100%"
    height="605px"
    :header-cell-style="{
      background: '#FAFAFA',
      color: 'rgba(0, 0, 0, 0.40)',
    }"
    :span-method="spanMethod"
  >
    <el-table-column prop="contractNo" label="合同编号" />
    <el-table-column prop="contractItem" label="合同项:" />

    <el-table-column prop="customerItemsContractItem" label="对客合同项" />
    <el-table-column
      prop="customerItemsCount"
      label="当天收费量(次)"
      align="right"
    >
      <template #default="scope">
        <span>{{ $utils.addCommas(scope.row.customerItemsCount) }}</span>
      </template>
    </el-table-column>

    <el-table-column prop="count" label="合同项当天收费量" align="center">
      <template #default="scope">
        <span>{{ $utils.addCommas(scope.row.count) }}</span>
      </template>
    </el-table-column>
  </el-table>

根据element文档所给的示例结合需求分析,需要把接口返回的数据进行格式化处理,把嵌套数据进行拆分,这里开始我是这样实现的(坑):

复制代码
const formatListFn = (list) => {
  let arr = [];
  for (let i = 0; i < list.length; i++) {
    const item = list[i];
    for (let j = 0; j < item["customerItems"].length; j++) {
      const itm = item["customerItems"][j];
      arr.push({
        customerItemsContractItem: itm.contractItem,
        customerItemsCount: itm.count,
        ...item,
      });
    }
  }
  // console.log(arr);
  return arr;
};

此处把嵌套数组中需要使用的字段提取了出来,自定义了属性名customerItemsContractItemcustomerItemsCount。其他属性原样复制即可,不需要进行额外操作。

然后定义并给 table 传入span-method方法来实现合并行或列:

复制代码
const spanMethod = ({ row, column, rowIndex, columnIndex }) => {
  const len = row["customerItems"].length;
  if (columnIndex > 3 || columnIndex < 2) {
    return {
      rowspan: len,
      colspan: 1,
    };
  }
};

根据索引给需要合并的部分设置rowspan,值为嵌套数组的长度。

此时以为大功告成,结果保存后查看页面如下:

可以看到框选处的展示是有问题的,对比需求效果如下:

4. 问题排查处理:

经过多处排查后发现问题出在spanMethod中。在spanMethod方法中,只判断了列索引,所以同一列可能会重复多次执行rowspan,导致合并错乱。

嵌套行被拆分后,原来两行数据被拆分成了三行,因此rowspan操作会多次执行。

解决办法就是让多行嵌套数据只执行一次rowspan操作。可以给每行数据添加标识,区分是否进行合并操作。这里我是这样处理的:

首先给每行数据设置rowspan值

复制代码
const formatListFn = (list) => {
  let arr = [];
  for (let i = 0; i < list.length; i++) {
    const item = list[i];
    for (let j = 0; j < item["customerItems"].length; j++) {
      const itm = item["customerItems"][j];
      arr.push({
        customerItemsContractItem: itm.contractItem,
        customerItemsCount: itm.count,
        ...item,
        rowspan: j === 0 ? item.customerItems.length : 0,
      });
    }
  }
  // console.log(arr);
  return arr;
};

注意这行 rowspan: j === 0 ? item.customerItems.length : 0,,每次遍历customerItems时,给第一项设置rowspan为customerItems.length。其余项设置为0,不执行合并。

然后修改spanMethod方法

复制代码
const spanMethod = ({ row, column, rowIndex, columnIndex }) => {
  if (columnIndex > 3 || columnIndex < 2) {
    return {
      rowspan: row.rowspan,
      colspan: 1,
    };
  }
};

注意这行rowspan: row.rowspan

刷新页面查看,问题解决:

相关推荐
Sheldon一蓑烟雨任平生3 天前
Vue3 表单输入绑定
vue.js·vue3·v-model·vue3 表单输入绑定·表单输入绑定·input和change区别·vue3 双向数据绑定
麦麦大数据3 天前
D026 vue3+django 论文知识图谱推荐可视化系统 | vue3+vite前端|neo4j 图数据库
前端·django·vue3·知识图谱·推荐算法·论文文献·科研图谱
duansamve4 天前
Vue3和vue2的Diff算法有何差异?
vue·vue3·vue2·diff
JNU freshman4 天前
Element Plus组件
前端·vue.js·vue3
Sheldon一蓑烟雨任平生7 天前
Vue3 列表渲染
vue.js·vue3·v-for·列表渲染·vue3 列表渲染·v-for 循环对象·v-for与计算属性
duansamve7 天前
TS在Vue3中的使用实例集合
typescript·vue3
ღ᭄ꦿ࿐Never say never꧂7 天前
微信小程序 Button 组件 open-type 完全指南:从用户信息获取到客服分享的实战应用
spring boot·微信小程序·小程序·uni-app·vue3
Sheldon一蓑烟雨任平生8 天前
Vue3 Class 与 Style 绑定
vue.js·vue3·class与style绑定·绑定class·绑定style·vue3绑定class·vue3绑定style
昔冰_G17 天前
Vue内置组件KeepAlive——缓存组件实例
vue.js·缓存·vue3·vue2·keep-alive·vue组件缓存·vue内置组件
wxr061619 天前
部署Spring Boot项目+mysql并允许前端本地访问的步骤
前端·javascript·vue.js·阿里云·vue3·springboot