element UI table单元格动态合并

104 阅读2分钟
  1. 新建src/hooks/useTableMerge.js,computeCell方法遍历整个表格数组,根据传入的字段生成一个数据,例如表格有8行,第一列需要纵向合并8个单元格,那么会返回一个数组[8,0,0,0,0,0,0,0,0],表示,在第一行的位置进行合并合并数量为8,第二列需要纵列两两合并,那么返回数组[2,0,2,0,2,0,2,0]
export default function () {
    /**
     *      根据表体数据,指定需要合并单元格的字段是那个
     *      返回统计出来的需要纵向合并的单元格信息
     * */
    const computeCell = (tableBody, key) => {
        let cellList = [];
        let count;
        for (let i = 0; i < tableBody.length; i++) {
            if (i === 0) {
                cellList.push(1);
                count = 0;
            } else {
                if (tableBody[i][key] === tableBody[i - 1][key]) {
                    cellList[count] += 1;
                    cellList.push(0);
                } else {
                    cellList.push(1);
                    count = i;
                }
            }
        }
        return cellList;
    }

    /**
     *      根据计算出来的需要纵向合并的单元格信息去合并
     *      返回的对象数据给到element UI objectSpanMethod使用
     * */
    const mergeCellVertical = (cellList, rowIndex) => {
        const rowCell = cellList[rowIndex];
        if (rowCell > 0) {
            const colCell = 1;
            return {
                rowspan: rowCell,
                colspan: colCell,
            };
        } else {
            return {
                rowspan: 0,
                colspan: 0,
            };
        }
    }

    return {
        computeCell,
        mergeCellVertical
    }
}
  1. 在组件中引入
import useTableMerge from '@/hooks/useTableMerge'

const {computeCell, mergeCellVertical} = useTableMerge()

onMounted(() => {
  calculateMerge()
})

// 第一列合并单元格信息
const cellList1_1 = ref([])
// 第二列合并单元格信息
const cellList1_2 = ref([])

const calculateMerge = () => {
  cellList1_1.value = computeCell(tableData1.value, "primaryIndicator");
  cellList1_2.value = computeCell(tableData1.value, "secondaryIndicator");
}
const tableData1 = ref([
  {
    primaryIndicator: '产出指标60分',
    secondaryIndicator: '数量指标(20分)',
    tertiaryIndicator: '',
    indicatorNature: '',
    indicatorValue: '',
    measurementUnit: '',
    weight: '',
    sort: 1
  }
  ...
]
/**
 * 计算单元格的合并范围。
 * 此方法用于确定表格中特定单元格是否应该被合并。它通过对行索引和列索引进行检查,来决定合并的逻辑。
 *
 * @param {Object} param0 包含单元格的行索引和列索引的对象。
 * @param {number} param0.rowIndex 单元格的行索引。
 * @param {number} param0.columnIndex 单元格的列索引。
 * @returns {Object|null} 返回一个对象来指定单元格的合并范围,如果不需要合并则返回null。
 */
const objectSpanMethod1 = ({ rowIndex, columnIndex}) => {
  // 当列索引为0或1时,检查是否需要进行纵向合并
  // 第一列的合并(竖向)
  if (columnIndex === 0) {
    return mergeCellVertical(cellList1_1.value, rowIndex);
  }
  // 第二列合并(竖向)
  if (columnIndex === 1) {
    return mergeCellVertical(cellList1_2.value, rowIndex);
  }
}
  1. 页面数据
<el-table :data="tableData1" :span-method="objectSpanMethod1"
          border>
  <el-table-column prop="primaryIndicator" label="一级指标"/>
  <el-table-column prop="secondaryIndicator" label="二级指标">
    <template #default="scope">
      <div>{{ scope.row.secondaryIndicator }}</div>
      <el-button link type="primary" size="small" @click="addItem(scope)">新增三级指标
      </el-button>
    </template>
  </el-table-column>
  <el-table-column prop="tertiaryIndicator" label="三级指标"/>
  <el-table-column prop="indicatorNature" label="绩效指标性质"/>
  <el-table-column prop="indicatorValue" label="绩效指标值"/>
  <el-table-column prop="measurementUnit" label="绩效度量单位"/>
  <el-table-column prop="weight" label="权重"/>
  <el-table-column fixed="right" label="操作" v-if="props.isEdit">
    <template #default="scope">
      <el-button link type="primary" size="small" @click="editItem(scope)">编辑
      </el-button>
      <el-popconfirm
          title="确认移除该条数据吗?"
          @confirm="removeItem(scope)"
      >
        <template #reference>
          <el-button size="small"  link type="danger">移除
          </el-button>
        </template>
      </el-popconfirm>
    </template>
  </el-table-column>
</el-table>

新增编辑移除

//新增
const addItem = ({$index, row}) => {
  operationTpe.value = 'add'
  operation.value = '新增指标'
  tableIndex.value = $index
  Object.keys(form).map(key => {
    form[key] = ''
  })
  form.primaryIndicator = row.primaryIndicator
  form.secondaryIndicator = row.secondaryIndicator
  dialogFormVisible.value = true
}

//新增确认
const confirm = () => {
  tableData1.value[tableIndex.value] = {...form}
  //将新增的数据添加到表格的指定位置后,需要重新合并一下表格
  calculateMerge()

  dialogFormVisible.value = false
}

image.png 新增三级指标

image.png

image.png

删除编辑同上