效果如下
关键参数
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;
}