el-table合并列实例

想要实现效果:

目前接口返回数据

复制代码
data:[
    {
      companyCode: "NXKYS",
      companyName:'1123',
      costContractId:'1123',
      costContractName:'1123',
      createBy:'1123',
      details:[
        {
          brand:'1123',
          contractItemName:'1123',
          modelSpec:'1123',
          projectItemId:'1123',
          requestQty:'1123',
          transactionZone:'1123'
        },
        {
          brand:'1123',
          contractItemName:'1123',
          modelSpec:'1123',
          projectItemId:'1123',
          requestQty:'1123',
          transactionZone:'1123'
        },
      ]
    },
    {
      companyCode: "NXKYS",
      companyName:'1123',
      costContractId:'1123',
      costContractName:'1123',
      createBy:'1123',
      details:[
        {
          brand:'1123',
          contractItemName:'1123',
          modelSpec:'1123',
          projectItemId:'1123',
          requestQty:'1123',
          transactionZone:'1123'
        },
        {
          brand:'1123',
          contractItemName:'1123',
          modelSpec:'1123',
          projectItemId:'1123',
          requestQty:'1123',
          transactionZone:'1123'
        },
      ]
    }
  ];

其中要根据details这个字段去进行展示图中标记的列。并将其他列进行合并。

首先要重新修改数据格式,方便进行合并以及列表渲染的展示。

接口返回的数据在tableData.value中

计算需要处理子表的数据

复制代码
const flattenedData = computed(() => {
    const result = [];
    const data = tableData.value;
    if (!data || !Array.isArray(data)) {
      return result;
    }
    data.forEach((mainItem, mainIndex) => {
      if (mainItem?.details && Array.isArray(mainItem.details) && mainItem.details.length > 0) {
        mainItem.details.forEach((detail, detailIndex) => {
          result.push({
            ...mainItem,
            ...detail,
            _mainIndex: mainIndex,
            _detailIndex: detailIndex
          });
        });
      } else {
        result.push({
          ...mainItem,
          _mainIndex: mainIndex, 
          _detailIndex: 0 // 这是 details 为空时的唯一一行
        });
      }
    });
    return result;
  
});

el-table中添加span-method方法

<el-table

ref="tableRef"

v-loading="tableLoading"

:data="flattenedData"

:height="tableHeight"

:header-cell-style="{ backgroundColor: '#F6F8FC' }"

highlight-current-row

:border="props.border"

v-bind="$attrs"

@current-change="handleSelectionChange"

@header-dragend="headerDragend"

:scrollbar-always-on="true"

:span-method="objectSpanMethod"

>

复制代码
const objectSpanMethod = ({ row, column, rowIndex, columnIndex }) => {
  const mergeColumns = [
    'documentCode',
    'costContractId',
    'costContractName',
    'supplierName',
    'handlerDepartmentDesc',
    'projectId',
    'projectName',
    'whName',
    'whCategoryDesc',
    'workflowStateDesc',
    'xz',
    'xh',
    'cz',
  ];
  const prop = column.property;
  if (!row) {
    console.warn('Row is undefined in objectSpanMethod');
    return { rowspan: 1, colspan: 1 };
  }
  if (row._mainIndex === undefined || row._mainIndex === null) {
    console.warn(`_mainIndex is ${row._mainIndex} for row at index ${rowIndex}`);
    return { rowspan: 1, colspan: 1 };
  }
  if (mergeColumns.includes(prop)) {
    const mainItemIndex = row._mainIndex;
    if (
      !tableData.value || 
      mainItemIndex < 0 ||
      mainItemIndex >= tableData.value.length 
    ) {
      console.error('Invalid mainItemIndex or tableData');
      return { rowspan: 1, colspan: 1 };
    }
    const mainItem = tableData.value[mainItemIndex]; 
    if (!mainItem) {
      console.error(`mainItem is missing for index ${mainItemIndex}`);
      return { rowspan: 1, colspan: 1 };
    }
    const details = mainItem.details || [];
    const detailCount = details.length;
    const effectiveRowspan = detailCount > 0 ? detailCount : 1;
    if (row._detailIndex === 0) {
      return {
        rowspan: effectiveRowspan,
        colspan: 1,
      };
    } else {
      return {
        rowspan: 0,
        colspan: 0,
      };
    }
  }
  return {
    rowspan: 1,
    colspan: 1,
  };
};

mergeColumns定义的是需要进行合并的列的props;

列表渲染就正常展示就可以

如:

<el-table-column

prop="transactionZone"

label="入库分区"

:show-overflow-tooltip="true"

width="150"

>

</el-table-column>