工作终到了多重表头,所以就用vue简单写了一个。以前也写过,但是感觉这次写的比较简单一些,所以就总结下。
html
<template>
<div class="exeicise-boxs">
<table>
<colgroup>
<template v-for="h in colMsgList">
<col :width="h.width" :key="Date.now() + h.prop" />
</template>
</colgroup>
<thead>
<tr v-for="(rows, rowIndex) in tableHeaderList" :key="rowIndex">
<th
v-for="header in rows"
:key="header.props"
:rowspan="header.rowSpan"
:colspan="header.colSpan"
>
{{ header.title }}
</th>
</tr>
</thead>
<tbody>
<tr v-for="(data, index) in tableDatas" :key="index + 'data'">
<template v-for="col in colMsgList">
<td :key="col.prop">{{ data[col.prop] }}</td>
</template>
</tr>
</tbody>
</table>
</div>
</template>
<script>
export default {
name: "HelloWorld",
created() {
this.multiTableHeaderHander(this.tableHeaders, 3); // 需要手动告诉函数,这次处理的几个层级的表头
console.log(
"multiTableHeaderHander",
this.tableHeaderList,
this.colMsgList
);
},
methods: {
multiTableHeaderHander(headerList, rowNum, initNum = 1) {
// 处理多层表头数据成为多个数组组成的Map()数据
const headerArr = [];
headerList.forEach(h => {
if (!h.chlidren) {
headerArr.push({
...h,
rowSpan: rowNum,
colSpan: 1
});
this.colMsgList.push({
width: h.width,
prop: h.prop
});
} else {
const child = this.multiTableHeaderHander(
h.chlidren,
rowNum - 1,
initNum + 1
);
headerArr.push({
...h,
rowSpan: 1,
colSpan: child.map(c => c.colSpan).reduce((pre, cur) => pre + cur)
});
}
});
if (this.tableHeaderMap.get(initNum)) {
this.tableHeaderMap.set(initNum, [
...this.tableHeaderMap.get(initNum),
...headerArr
]);
} else {
this.tableHeaderMap.set(initNum, [...headerArr]);
}
return headerArr;
}
},
computed: {
tableHeaderList() {
// 把Map()转化成为数组,便于遍历。
const arr = [];
this.tableHeaderMap.forEach((value, key) => {
arr[key - 1] = value;
});
return arr;
}
},
data() {
return {
colMsgList: [], //在递归的时候,收集每个展示信息数据td的宽度和prop。
tableHeaderMap: new Map(), //用来把不通层级的表头数据,用[]分隔开,有利于后期的表头的循环遍历
tableHeaders: [
// 表头内容
{ title: "序号", prop: "seqNo", width: 60 },
{
title: "班级",
width: 500,
chlidren: [
{ title: "班号", prop: "classNm", width: 100 },
{
title: "学生",
chlidren: [
{ title: "姓名", prop: "name", width: 80 },
{ title: "性别", prop: "gender", width: 60 },
{ title: "总分", prop: "grade", width: 60 },
{ title: "爱好", prop: "hobby", width: 200 }
]
}
]
},
{
title: "各科成绩汇总",
width: 180,
chlidren: [
{ title: "语文", prop: "chinese", width: 60 },
{ title: "数学", prop: "math", width: 60 },
{ title: "英语", prop: "english", width: 60 }
]
},
{
title: "各科老师评价",
width: 360,
chlidren: [
{ title: "语文老师", prop: "chineseT", width: 90 },
{ title: "数学老师", prop: "mathT", width: 90 },
{ title: "英语老师", prop: "englishT", width: 90 }
]
},
{ title: "年级主任总结", prop: "directorComment", width: 200 }
],
tableDatas: [
//标题数据
{
seqNo: 1,
classNm: "三年二班",
name: "huyi",
gender: "男",
grade: "294",
hobby: "唱跳rapper,篮球",
chinese: "98",
math: "98",
english: "98",
chineseT: "比较懒",
mathT: "比较聪明",
englishT: "记忆里还可以",
directorComment: "也就那样继续努力"
}
]
};
}
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
table {
border-collapse: collapse;
}
table th,
table td {
padding: 10px;
border: 1px solid #000;
}
th {
background: #ccc;
}
</style>
数据处理为:

实现效果如下:
