共计 8876 个字符,预计需要花费 23 分钟才能阅读完成。
问题形容
本文记录 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
假如咱们须要做一个周一到周末的表格,记录一下工作内容,如下效果图:
对应代码是这样的:
<table border="1">
<tr>
<th> 工作日 </th>
<th> 工作日 </th>
<th> 工作日 </th>
<th> 工作日 </th>
<th> 工作日 </th>
<th> 周末 </th>
<th> 周末 </th>
</tr>
<tr>
<th> 周一 </th>
<th> 周二 </th>
<th> 周三 </th>
<th> 周四 </th>
<th> 周五 </th>
<th> 周六 </th>
<th> 周日 </th>
</tr>
<tr>
<td> 下班 </td>
<td> 下班 </td>
<td> 下班 </td>
<td> 下班 </td>
<td> 下班 </td>
<td> 加班 </td>
<td> 加班 </td>
</tr>
</table>
然而,咱们想把五个工作日和两个周末进行合并一下,这样看起来更加优雅一些,如下需要
- 由图示,咱们晓得第一行的工作日一共有 5 个,咱们
先
把后 4 个工作日隐去使其隐没, 再
让第一个工作日横跨 5 个单元格宽度,即横跨 5 列(本来默认都是横跨 1 列)
先隐去后四个工作日单元格
<tr>
<th> 工作日 </th>
<th style="display: none;"> 工作日 </th>
<th style="display: none;"> 工作日 </th>
<th style="display: none;"> 工作日 </th>
<th style="display: none;"> 工作日 </th>
<th> 周末 </th>
<th> 周末 </th>
</tr>
变成这样的成果了
- 这样的话,咱们只须要,再让第一个工作日单元格宽度变宽一些,占据五个单元格,这样的话,宽度有了,就把两个周末挤回到原来失常的地位了
- 那,如何让第一个工作日单元格,占据五个单元格的宽度呢?
- 或者说,如何让一个单元格横跨 5 列?
- 很简略:
<th colspan="5"> 工作日 </th>
即可 rowspan
同理,不赘述
需要实现效果图:
对应需要实现代码:
<table border="1">
<tr>
<th colspan="5"> 工作日 </th>
<th style="display: none;"> 工作日 </th>
<th style="display: none;"> 工作日 </th>
<th style="display: none;"> 工作日 </th>
<th style="display: none;"> 工作日 </th>
<th colspan="2"> 周末 </th>
<th style="display: none;"> 周末 </th>
</tr>
<tr>
<th> 周一 </th>
<th> 周二 </th>
<th> 周三 </th>
<th> 周四 </th>
<th> 周五 </th>
<th> 周六 </th>
<th> 周日 </th>
</tr>
<tr>
<td> 下班 </td>
<td> 下班 </td>
<td> 下班 </td>
<td> 下班 </td>
<td> 下班 </td>
<td> 加班 </td>
<td> 加班 </td>
</tr>
</table>
所以,通过下面的 demo,咱们能够得出一个论断:
合并单元格法则论断
- 合并单元格须要 先暗藏相干单元格,再让某个单元格横向或竖向延长宽度或高度
- 合并单元格须要 先暗藏相干单元格,再让某个单元格横跨列,或竖跨行
最初咱们审查一下 dom
元素,发现还真是这样的
el-table 单层表头合并案例
无论是饿了么 UI 还是 Iview 等相干的 UI 组件库,都是 给原生 table 套壳子封装
的,所以若是须要合并相应单元格,咱们仍旧能够应用上述的思维形式
咱们持续通过案例来看一下,在 UI 组件库中如何操作合并单元格
本文以表头单元格合并举例,若是有表体单元格合并的需要,能够看笔者之前的这篇文章:https://segmentfault.com/a/1190000040927939
案例一
效果图:
代码:
header-cell-style
函数用于给表头增加款式,其返回的值会被增加到表头对应款式中去- 留神函数的形参中的
column.id
为单元格的class
类 - 大家最好打印一下,联合审查
dom
看类名
<template>
<el-table
:data="tableData"
border
style="width: 600"
:header-cell-style="headerCellStyle"
>
<el-table-column
prop="name"
label="姓名、年龄、他乡"
width="150"
align="center"
></el-table-column>
<el-table-column
prop="age"
label="年龄"
width="150"
align="center"
></el-table-column>
<el-table-column
prop="home"
label="他乡"
width="150"
align="center"
></el-table-column>
<el-table-column
prop="hobby"
label="喜好"
width="150"
align="center"
></el-table-column>
</el-table>
</template>
<script>
export default {data() {
return {
tableData: [
{
name: "孙悟空",
age: 500,
home: "花果山水帘洞",
hobby: "大闹天宫",
},
{
name: "猪八戒",
age: 88,
home: "高老庄",
hobby: "吃包子",
},
{
name: "沙和尚",
age: 1000,
home: "通天河",
hobby: "游泳",
},
{
name: "唐僧",
age: 99999,
home: "东土大唐",
hobby: "取西经",
},
],
};
},
methods: {headerCellStyle({ row, column, rowIndex, columnIndex}) {
// 第一步:设置表头的第 0 列暂不操作,将地 1 列和第 2 列隐去使其隐没
if ((columnIndex == 1) | (columnIndex == 2)) {return { display: "none"};
}
// 第二步,因为 1、2 列没有了,后续列就会贴上来(后续列往左错位问题)if ((rowIndex == 0) & (columnIndex == 0)) {
// 解决后续列错位问题,就是将隐去的第 1、2 列的地位再补上,通过第 0 列来补
this.$nextTick(() => {
// 原来第 0 列只占据一个地位,当初要去占据三个地位。即占据三列,即设置为横向三个单元格
document.querySelector(`.${column.id}`).setAttribute("colspan", "3");
// 这里的 column.id 理论是 dom 元素的 class,故用点. 不必井 #,可审查 dom 验证
// 通过设置原生的 colspan 属性,让原来的第一列只占据一个单元格的表头占据 3 个单元格即可
});
}
},
},
};
</script>
<style lang="less">
.el-table {
th {
font-weight: bold;
color: #333;
}
}
</style>
看,基本上一样的用法:先暗藏再设置横跨竖跨单元格
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 标签进行嵌套
<template>
<el-table
:data="tableData"
border
style="width: 600"
:header-cell-style="headerCellStyle"
>
<el-table-column prop="name" label="姓名" width="150" align="center">
<el-table-column
prop="name"
label="三列根底信息"
width="150"
align="center"
></el-table-column>
</el-table-column>
<el-table-column prop="name" label="年龄" width="150" align="center">
<el-table-column
prop="age"
label="年龄"
width="150"
align="center"
></el-table-column>
</el-table-column>
<el-table-column prop="name" label="他乡" width="150" align="center">
<el-table-column
prop="home"
label="他乡"
width="150"
align="center"
></el-table-column>
</el-table-column>
<el-table-column
prop="hobby"
label="喜好"
width="150"
align="center"
></el-table-column>
</el-table>
</template>
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");
});
}
},
案例六
效果图:
代码:
仍旧是嵌套
<template>
<el-table
:data="tableData"
border
style="width: 600"
:header-cell-style="headerCellStyle"
>
<el-table-column
prop="name"
label="根本信息(姓名、年龄、他乡)"
align="center"
>
</el-table-column>
<el-table-column
prop="age"
label="年龄"
align="center"
>
</el-table-column>
<el-table-column
prop="home"
label="他乡"
align="center"
>
</el-table-column>
<el-table-column prop="kind" label="所属种族" align="center">
</el-table-column>
<el-table-column label="重要信息" align="center">
<el-table-column label="公开重要信息" align="center">
<el-table-column prop="nickname" label="法号" align="center">
</el-table-column>
<el-table-column prop="hobby" label="喜好 & 性情" align="center">
</el-table-column>
<el-table-column prop="personality" label="性情" align="center">
</el-table-column>
</el-table-column>
<el-table-column label="窃密重要信息" align="center">
<el-table-column prop="bornBackground" label="出身背景" align="center">
</el-table-column>
<el-table-column prop="skill" label="技能" align="center">
</el-table-column>
</el-table-column>
</el-table-column>
</el-table>
</template>
<style lang="less">
.el-table {
th {
font-weight: bold;
color: #333;
}
}
</style>
先找到 dom,再操作 dom
<script>
export default {data() {
return {
tableData: [
{
name: "孙悟空",
age: 500,
home: "花果山水帘洞",
kind: "monkey",
nickname: "斗战败佛",
hobby: "大闹天宫",
personality: "怯懦坚韧、疾恶如仇",
bornBackground: "仙石孕育而生",
skill: "72 变、筋斗云",
},
{
name: "猪八戒",
age: 88,
home: "高老庄",
kind: "pig",
nickname: "净坛使者",
hobby: "吃包子",
personality: "好逸恶劳、贪图女色",
bornBackground: "天蓬元帅错投猪胎",
skill: "36 变",
},
{
name: "沙和尚",
age: 1000,
home: "通天河",
kind: "human",
nickname: "金身罗汉",
hobby: "游泳",
personality: "憨厚老实、不辞辛苦",
bornBackground: "卷帘大将被贬下界",
skill: "18 变",
},
{
name: "唐僧",
age: 99999,
home: "东土大唐",
kind: "human",
nickname: "檀功德佛",
hobby: "取西经",
personality: "谦恭儒雅、愚善执著",
bornBackground: "金蝉子转世",
skill: "念紧箍咒",
},
],
};
},
methods: {headerCellStyle({ row, column, rowIndex, columnIndex}) {
/**
* 合并:根本信息(姓名、年龄、他乡)单元格【通过行与列的索引来合并】* */
let colArr = [1, 2];
if (colArr.includes(columnIndex)) {if (rowIndex == 0) {
// 把第 1 列第 0 行和第 2 列第 0 行的单元格隐去
return {display: "none"};
}
}
if ((columnIndex == 0) & (rowIndex == 0)) {
// 把第 0 列第 0 行的单元格横向延长,补上刚刚隐去的单元格地位,并上个色
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"}; // 不加这个也行,加了只是为了更好辨别
}
/**
* 重要!重要!重要!* 咱们想要合并表头的单元格,须要先找到对应单元格
* 能够通过列 column 对象的 label 或者行与列索引来找到,找到当前进行暗藏或合并
* 也能够遍历行 row 数组找,不过会麻烦一些,集体倡议通过 column 来找
* */
// 通过 column 找
if (column.label == "技能") {return { background: "#baf"};
}
// 通过 row 找
for (const item of row) {if (item.label == "重要信息") {this.$nextTick(() => {document.querySelector(`.${item.id}`).style.background = "#ea66a6";
});
break;
}
}
},
},
};
</script>
- 还能够,间接通过 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…