制作一个多层表头的实现

工作终到了多重表头,所以就用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>

数据处理为:

实现效果如下:

相关推荐
码丁_11724 分钟前
为什么前端需要做优化?
前端
Mr Xu_35 分钟前
告别硬编码:前端项目中配置驱动的实战优化指南
前端·javascript·数据结构
Byron07071 小时前
从 0 到 1 搭建 Vue 前端工程化体系:提效、提质、降本实战落地
前端·javascript·vue.js
哆啦code梦1 小时前
前端存储三剑客:localStorage、sessionStorage与Cookie解析
前端·前端存储
zhengfei6111 小时前
【AI平台】- 基于大模型的知识库与知识图谱智能体开发平台
vue.js·语言模型·langchain·知识图谱·多分类
徐小夕@趣谈前端1 小时前
Web文档的“Office时刻“:jitword共建版2.0发布!让浏览器变成本地生产力
前端·数据结构·vue.js·算法·开源·编辑器·es6
Data_Journal2 小时前
如何使用 Python 解析 JSON 数据
大数据·开发语言·前端·数据库·人工智能·php
德育处主任Pro2 小时前
纯前端网格路径规划:PathFinding.js的使用方法
开发语言·前端·javascript
墨笔.丹青2 小时前
基于QtQuick开发界面设计出简易的HarmonyUI界面----下
开发语言·前端·javascript
董世昌412 小时前
深度解析浅拷贝与深拷贝:底层逻辑、实现方式及实战避坑
前端·javascript·vue.js