问题描述
本文记录el-table
表头合并的多种情况,并提出对应解决方案,估计能帮到部分道友
原生table知识点复习
- 我们知道:一个简单的
table
表格一般由一个或多个tr
、th
或td
标签组成(嵌套) tr
标签定义表格行(table-row
即为tr
)th
标签定义表头(table-header
即为th
)td
标签定义表格单元格
再复杂的表格还包括caption
、col
、colgroup
、thead
、tfoot
、tbody
等标签,这里暂不延伸
而合并单元格主要使用的是colspan
和rouspan
属性,即为可设置横跨列
和横跨行
的值
而合并单元格主要使用的是colspan
和rouspan
属性,即为可设置横跨列
和横跨行
的值
而合并单元格主要使用的是colspan
和rouspan
属性,即为可设置横跨列
和横跨行
的值
知道这两个属性以后,我们结合一个具体demo来看,就很好的理解了
原生表格demo
假设我们需要做一个周一到周末的表格,记录一下工作内容,如下效果图:
对应代码是这样的:
工作日
工作日
工作日
工作日
工作日
周末
周末
周一
周二
周三
周四
周五
周六
周日
上班
上班
上班
上班
上班
加班
加班
但是,我们想把五个工作日和两个周末进行合并一下,这样看起来更加优雅一些,如下需求
- 由图示,我们知道第一行的工作日一共有5个,我们
先
把后4个工作日隐去使其消失, 再
让第一个工作日横跨5个单元格宽度,即横跨5列(原本默认都是横跨1列)
先隐去后四个工作日单元格
工作日
周末
周末
变成这样的效果了
- 这样的话,我们只需要,再让第一个工作日单元格宽度变宽一些,占据五个单元格,这样的话,宽度有了,就把两个周末挤回到原来正常的位置了
- 那,如何让第一个工作日单元格,占据五个单元格的宽度呢?
- 或者说,如何让一个单元格横跨5列?
- 很简单:
即可工作日 rowspan
同理,不赘述
需求完成效果图:
对应需求完成代码:
工作日
周末
周一
周二
周三
周四
周五
周六
周日
上班
上班
上班
上班
上班
加班
加班
所以,通过上面的demo,我们可以得出一个结论:
合并单元格规律结论
- 合并单元格需要 先隐藏相关单元格,再让某个单元格横向或竖向延伸宽度或高度
- 合并单元格需要 先隐藏相关单元格,再让某个单元格横跨列,或竖跨行
最后我们审查一下dom
元素,发现还真是这样的
el-table单层表头合并案例
无论是饿了么UI还是Iview等相关的UI组件库,都是给原生table套壳子封装
的,所以若是需要合并相应单元格,我们依旧可以使用上述的思想方式
我们继续通过案例来看一下,在UI组件库中如何操作合并单元格
本文以表头单元格合并举例,若是有表体单元格合并的需求,可以看笔者之前的这篇文章:https://segmentfault.com/a/1190000040927939
案例一
效果图:
代码:
header-cell-style
函数用于给表头添加样式,其返回的值会被添加到表头对应样式中去- 注意函数的形参中的
column.id
为单元格的class
类 - 大家最好打印一下,结合审查
dom
看类名
看,基本上一样的用法:先隐藏再设置横跨竖跨单元格
colspan='number' 属性,设置单元格可以横跨几列(默认一个单元格横向只占据一列)
案例二
效果图:
代码:
headerCellStyle({ row, column, rowIndex, columnIndex }) {
// 第一步:隐去第2列单元格
if (columnIndex == 2) {
return { display: "none" };
}
// 第二步,让第1列单元格横跨两列(默认单元格只是横跨一列)
if ((rowIndex == 0) & (columnIndex == 1)) {
this.$nextTick(() => {
document.querySelector(`.${column.id}`).setAttribute("colspan", "2");
});
}
},
案例三
效果图:
代码:
headerCellStyle({ row, column, rowIndex, columnIndex }) {
// 第一步:隐去第3列单元格
if (columnIndex == 3) {
return { display: "none" };
}
// 第二步,让第2列单元格横跨两列(默认单元格只是横跨一列)
if ((rowIndex == 0) & (columnIndex == 2)) {
this.$nextTick(() => {
document.querySelector(`.${column.id}`).setAttribute("colspan", "2");
});
}
},
案例四
效果图:
代码:
headerCellStyle({ row, column, rowIndex, columnIndex }) {
// 第一步:隐去第1、2、3列单元格
let hideColArr = [1, 2, 3];
if (hideColArr.includes(columnIndex)) {
return { display: "none" };
}
// 第二步,让第0列单元格横跨四列(默认单元格只是横跨一列)
if ((rowIndex == 0) & (columnIndex == 0)) {
this.$nextTick(() => {
document.querySelector(`.${column.id}`).setAttribute("colspan", "4");
});
}
},
el-table多级表头合并案例
- 多级表头,需要进一步通过
rowIndex
去找到对应的单元格 - 因为单层表头,表头只有1行,
rowIndex
肯定是0,所以写不写都无所谓 - 但是多级表头有不少行,所以需要使用
columnIndex,rowIndex
进一步定位单元格 - 类似于通过
X轴 Y轴
的坐标定位到某个单元格位置
案例五
效果图:
代码:
html部门需要el-table-column标签进行嵌套
js部分继续先隐藏再延伸相关单元格
headerCellStyle({ row, column, rowIndex, columnIndex }) {
// 把第1列第1行和第2列第1行的单元格隐去
if ((columnIndex == 1) | (columnIndex == 2)) {
if (rowIndex == 1) { // 加上rowIndex精准定位
return { display: "none" };
}
}
// 然后让第0列第1行的单元格横向占据3个单元格位置填充刚刚隐去导致的空白
if ((columnIndex == 0) & (rowIndex == 1)) { // 加上rowIndex精准定位
this.$nextTick(() => {
document.querySelector(`.${column.id}`).setAttribute("colspan", "3");
});
}
},
案例六
效果图:
代码:
依旧是嵌套
先找到dom,再操作dom
- 还可以,直接通过column.label找到对应单元格,然后进行合并单元格操作,不使用rowIndex和columnIndex了
- 这种方式,在某些情况下,会更加方便
- 但无论哪种方式,本质思路都是先找到单元格,再进行合并相关操作
headerCellStyle({ row, column, rowIndex, columnIndex }) {
// 第一部分的合并
if (column.label == "年龄") {
return { display: "none" };
}
if (column.label == "家乡") {
return { display: "none" };
}
if (column.label == "基本信息(姓名、年龄、家乡)") {
this.$nextTick(() => {
document.querySelector(`.${column.id}`).setAttribute("colspan", "3");
});
return { background: "pink" };
}
// 第二部分的合并
if (column.label == "性格") {
return { display: "none" };
}
if (column.label == "爱好&性格") {
this.$nextTick(() => {
document.querySelector(`.${column.id}`).setAttribute("colspan", "2");
});
return { background: "orange" };
}
},
总结
读到这里,大家对表头合并相关问题应该都能应对了,若是还有不能应对的,可以发到评论区,大家一块帮忙解决
A good memory is better than a bad pen. Write it down...