el-table 合并列

128 阅读2分钟

效果如下

image.png

关键参数

span-method:实现合并行或列, 方法的参数是一个对象,里面包含当前行row、当前列column、当前行号rowIndex、当前列号columnIndex四个属性
row-class-name:为行设置class
@cell-mouse-leave,@cell-mouse-enter 鼠标移入移除事件

实现代码

      <el-table
        class="table"
        :data="tableData"
        border
        :span-method="objectSpanMethod"
        :row-class-name="tableRowClassName"
        @cell-mouse-leave="cellMouseLeave"
        @cell-mouse-enter="cellMouseEnter"
        style="flex: 1"
      >
        <el-table-column label="序号" type="index" align="center" header-align="center" width="60" />
        <el-table-column align="center" header-align="center" prop="checkItem" label="" min-width="40" />
        <el-table-column align="center" header-align="center" prop="inspectionContent" label="" min-width="70" />
        <el-table-column align="center" header-align="center" prop="inspectionResult" min-width="80" label="" />
        <el-table-column align="center" header-align="center" prop="remark" label="备注" min-width="40" />
      </el-table>
// 需要合并的列
const cellList = ref([])
const curRowArr = ref([])
const tableData = ref([])
const reportInfo = ref({})
const sameRowArr = ref([]) // 同一行数组索引

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 }
  }
}

const objectSpanMethod = ({ rowIndex, columnIndex }) => {
  // 处理第二列合并
  if (columnIndex === 1) {
    return mergeCellVertical(cellList.value, rowIndex)
  }
}

const computeCell = (tableBody, key) => {
  // 计算单元格合并
  let cellList = []
  let count
  for (let i = 0; i < tableBody.length; i++) {
    if (i == 0) {
      // 如果是第一行,直接添加1
      cellList.push(1)
      count = 0
    } else {
      // 如果当前行的key值与上一行的key值相同,则合并单元格
      if (tableBody[i][key] == tableBody[i - 1][key]) {
        cellList[count] += 1
        cellList.push(0)
      } else {
        // 如果不同,则添加1,并更新count
        cellList.push(1)
        count = i
      }
    }
  }
  return cellList
}

// 处理数据
const handleData = () => {
  // 处理合并数据 checkItem合并的字段
  cellList.value = computeCell(tableData2.value, 'checkItem')
  // 给tableData2每一项添加索引属性
  let arr = [],
    sIdx = 0
  tableData2.value.forEach((item, index) => {
    item.index = index
    if (index === 0) {
      arr.push([index])
    } else {
      // 如果当前行的 project 与上一行相同
      if (item.checkItem === tableData2.value[index - 1].checkItem) {
        // 将当前行的索引加入同一行数组的当前分组
        arr[sIdx].push(index)
      } else {
        // 如果 project 不同,创建新的一组
        sIdx = sIdx + 1
        arr.push([index])
      }
    }
    sameRowArr.value = arr
  })
}

const tableRowClassName = (row) => {
  // 根据当前行索引判断是否需要高亮
  for (let i = 0; i < curRowArr.value.length; i++) {
    // 如果当前行索引在高亮行索引数组中
    if (row.rowIndex == curRowArr.value[i]) {
      // 返回自定义的高亮样式类
      return 'row-class'
    }
  }
}

// 鼠标移入单元格时触发的方法
const cellMouseEnter = (row) => {
  // 遍历sameRowArr,找到包含当前行索引的数组,并赋值给curRowArr
  sameRowArr.value.forEach((item) => {
    if (item.includes(row.index)) {
      curRowArr.value = item
    }
  })
}

// 鼠标移出单元格时触发的方法
const cellMouseLeave = () => {
  // 清空高亮行的索引数组
  curRowArr.value = []
}
:deep(.row-class) {
	background-color: #f5f7fa;
}