el-table动态生成多级表头的表格(js + ts)

展示形式:

详细代码:

(js)

javascript 复制代码
<template>
    <div>
      <el-table :data="tableData" style="width: 100%">
        <el-table-column label="题目信息" align="center">
          <el-table-column prop="questionName" label="题目名称"></el-table-column>
          <el-table-column prop="fullScore" label="满分"></el-table-column>
          <el-table-column prop="gradeAvg" label="年级均分"></el-table-column>
          <el-table-column prop="gradeScoreRate" label="年级分数线"></el-table-column>
        </el-table-column>
        <el-table-column v-for="classInfo in classHeaders" :key="classInfo.classScoreId">
          <template #header>
            {{ classInfo.className }}
          </template>
          <el-table-column label="班级均分" align="center">
            <template #default="{ row }">{{ getCellValue(row, classInfo, 'classAvg') }}</template>
          </el-table-column>
          <el-table-column label="班级分数线" align="center">
            <template #default="{ row }">{{ getCellValue(row, classInfo, 'classScoreRate') }}</template>
          </el-table-column>
        </el-table-column>
      </el-table>
    </div>
  </template>
  
  <script>
  import { reactive } from 'vue';
  
  export default {
    data() {
      return {
        tableData: reactive([
  {
    id: 1,
    questionId: 1,
    questionName: '填空题',
    fullScore: 10,
    gradeAvg: 8,
    gradeScoreRate: 0.8,
    questionClassVOList: [{
      classScoreId: 1,
      className: '一班',
      classAvg: 7,
      classScoreRate: 0.7
    }, {
      classScoreId: 2,
      className: '二班',
      classAvg: 8,
      classScoreRate: 0.8
    }, {
      classScoreId: 3,
      className: '三班',
      classAvg: 8,
      classScoreRate: 0.8
    }, {
      classScoreId: 4,
      className: '四班',
      classAvg: 8,
      classScoreRate: 0.8
    }]
  }, {
    id: 2,
    questionId: 2,
    questionName: '选择题',
    fullScore: 10,
    gradeAvg: 8,
    gradeScoreRate: 0.8,
    questionClassVOList: [{
      classScoreId: 1,
      className: '一班',
      classAvg: 8,
      classScoreRate: 0.8
    }, {
      classScoreId: 2,
      className: '二班',
      classAvg: 8,
      classScoreRate: 0.8
    }, {
      classScoreId: 3,
      className: '三班',
      classAvg: 8,
      classScoreRate: 0.8
    }, {
      classScoreId: 4,
      className: '四班',
      classAvg: 8,
      classScoreRate: 0.8
    }]
  }, {
    id: 3,
    questionId: 3,
    questionName: '判断题',
    fullScore: 10,
    gradeAvg: 8,
    gradeScoreRate: 0.8,
    questionClassVOList: [{
      classScoreId: 1,
      className: '一班',
      classAvg: 8,
      classScoreRate: 0.8
    }, {
      classScoreId: 2,
      className: '二班',
      classAvg: 8,
      classScoreRate: 0.8
    }, {
      classScoreId: 3,
      className: '三班',
      classAvg: 8,
      classScoreRate: 0.8
    }, {
      classScoreId: 4,
      className: '四班',
      classAvg: 8,
      classScoreRate: 0.8
    }]
  }, {
    id: 4,
    questionId: 4,
    questionName: '填空题',
    fullScore: 10,
    gradeAvg: 8,
    gradeScoreRate: 0.8,
    questionClassVOList: [{
      classScoreId: 1,
      className: '一班',
      classAvg: 8,
      classScoreRate: 0.8
    }, {
      classScoreId: 2,
      className: '二班',
      classAvg: 8,
      classScoreRate: 0.8
    }, {
      classScoreId: 3,
      className: '三班',
      classAvg: 8,
      classScoreRate: 0.8
    }, {
      classScoreId: 4,
      className: '四班',
      classAvg: 8,
      classScoreRate: 0.8
    }]
  }, {
    id: 5,
    questionId: 5,
    questionName: '简答题',
    fullScore: 10,
    gradeAvg: 8,
    gradeScoreRate: 0.8,
    questionClassVOList: [{
      classScoreId: 1,
      className: '一班',
      classAvg: 8,
      classScoreRate: 0.8
    }, {
      classScoreId: 2,
      className: '二班',
      classAvg: 8,
      classScoreRate: 0.8
    }, {
      classScoreId: 3,
      className: '三班',
      classAvg: 8,
      classScoreRate: 0.8
    }, {
      classScoreId: 4,
      className: '四班',
      classAvg: 8,
      classScoreRate: 0.8
    }]
  }
])  // 你的数据结构
      };
    },
    computed: {
      classHeaders() {
        // 假设每个问题类型下的班级信息结构是一样的,取第一个问题类型下的班级信息来生成表头
        const firstQuestion = this.tableData[0];
        if (firstQuestion) {
          return firstQuestion.questionClassVOList;
        }
        return [];
      }
    },
    methods: {
      getCellValue(row, classInfo, prop) {
        const classData = row.questionClassVOList.find(item => item.classScoreId === classInfo.classScoreId);
        return classData ? classData[prop] : '';
      }
    }
  };
  </script>
  
  <style>
  /* 样式可以根据你的需求进行调整 */
  </style>
  

(ts)

typescript 复制代码
<template>
    <div>
        <el-table :data="tableData" style="width: 100%">
            <el-table-column label="题目信息" align="center">
                <el-table-column prop="questionName" label="题目名称"></el-table-column>
                <el-table-column prop="fullScore" label="满分"></el-table-column>
                <el-table-column prop="gradeAvg" label="年级均分"></el-table-column>
                <el-table-column prop="gradeScoreRate" label="年级分数线"></el-table-column>
            </el-table-column>
            <el-table-column v-for="classInfo in classHeaders" :key="classInfo.classScoreId">
                <template #header>
                    {{ classInfo.className }}
                </template>
                <el-table-column label="班级均分" align="center">
                    <template #default="{ row }">{{ getCellValue(row, classInfo, 'classAvg') }}</template>
                </el-table-column>
                <el-table-column label="班级分数线" align="center">
                    <template #default="{ row }">{{ getCellValue(row, classInfo, 'classScoreRate') }}</template>
                </el-table-column>
            </el-table-column>
        </el-table>
    </div>
</template>
  
<script setup lang="ts">
import { ref, reactive, computed } from 'vue';

interface ClassInfo {
    classScoreId: number;
    className: string;
    classAvg: number;
    classScoreRate: number;
}

interface QuestionClass {
    questionClassVOList: ClassInfo[];
}

interface TableRow extends QuestionClass {
    questionId: number;
    questionName: string;
    fullScore: number;
    gradeAvg: number;
    gradeScoreRate: number;
}

const tableData = reactive<TableRow[]>([
    {
        questionId: 1,
        questionName: '填空题',
        fullScore: 10,
        gradeAvg: 8,
        gradeScoreRate: 0.8,
        questionClassVOList: [{
            classScoreId: 1,
            className: '一班',
            classAvg: 7,
            classScoreRate: 0.7
        }, {
            classScoreId: 2,
            className: '二班',
            classAvg: 8,
            classScoreRate: 0.8
        }, {
            classScoreId: 3,
            className: '三班',
            classAvg: 8,
            classScoreRate: 0.8
        }, {
            classScoreId: 4,
            className: '四班',
            classAvg: 8,
            classScoreRate: 0.8
        }]
    }, {
        questionId: 2,
        questionName: '选择题',
        fullScore: 10,
        gradeAvg: 8,
        gradeScoreRate: 0.8,
        questionClassVOList: [{
            classScoreId: 1,
            className: '一班',
            classAvg: 8,
            classScoreRate: 0.8
        }, {
            classScoreId: 2,
            className: '二班',
            classAvg: 8,
            classScoreRate: 0.8
        }, {
            classScoreId: 3,
            className: '三班',
            classAvg: 8,
            classScoreRate: 0.8
        }, {
            classScoreId: 4,
            className: '四班',
            classAvg: 8,
            classScoreRate: 0.8
        }]
    }, {
        questionId: 3,
        questionName: '判断题',
        fullScore: 10,
        gradeAvg: 8,
        gradeScoreRate: 0.8,
        questionClassVOList: [{
            classScoreId: 1,
            className: '一班',
            classAvg: 8,
            classScoreRate: 0.8
        }, {
            classScoreId: 2,
            className: '二班',
            classAvg: 8,
            classScoreRate: 0.8
        }, {
            classScoreId: 3,
            className: '三班',
            classAvg: 8,
            classScoreRate: 0.8
        }, {
            classScoreId: 4,
            className: '四班',
            classAvg: 8,
            classScoreRate: 0.8
        }]
    }, {
        questionId: 4,
        questionName: '填空题',
        fullScore: 10,
        gradeAvg: 8,
        gradeScoreRate: 0.8,
        questionClassVOList: [{
            classScoreId: 1,
            className: '一班',
            classAvg: 8,
            classScoreRate: 0.8
        }, {
            classScoreId: 2,
            className: '二班',
            classAvg: 8,
            classScoreRate: 0.8
        }, {
            classScoreId: 3,
            className: '三班',
            classAvg: 8,
            classScoreRate: 0.8
        }, {
            classScoreId: 4,
            className: '四班',
            classAvg: 8,
            classScoreRate: 0.8
        }]
    }, {
        questionId: 5,
        questionName: '简答题',
        fullScore: 10,
        gradeAvg: 8,
        gradeScoreRate: 0.8,
        questionClassVOList: [{
            classScoreId: 1,
            className: '一班',
            classAvg: 8,
            classScoreRate: 0.8
        }, {
            classScoreId: 2,
            className: '二班',
            classAvg: 8,
            classScoreRate: 0.8
        }, {
            classScoreId: 3,
            className: '三班',
            classAvg: 8,
            classScoreRate: 0.8
        }, {
            classScoreId: 4,
            className: '四班',
            classAvg: 8,
            classScoreRate: 0.8
        }]
    }
])

const classHeaders = computed<ClassInfo[]>(() => {
    const firstQuestion = tableData[0];
    if (firstQuestion) {
        return firstQuestion.questionClassVOList;
    }
    return [];
});

const getCellValue = (row: TableRow, classInfo: ClassInfo, prop: keyof ClassInfo) => {
    const classData = row.questionClassVOList.find(item => item.classScoreId === classInfo.classScoreId);
    return classData ? classData[prop] : '';
};
</script>
  
<style lang="scss" scoped>
</style>
  
相关推荐
吕彬-前端4 分钟前
使用vite+react+ts+Ant Design开发后台管理项目(五)
前端·javascript·react.js
学前端的小朱6 分钟前
Redux的简介及其在React中的应用
前端·javascript·react.js·redux·store
guai_guai_guai16 分钟前
uniapp
前端·javascript·vue.js·uni-app
bysking1 小时前
【前端-组件】定义行分组的表格表单实现-bysking
前端·react.js
王哲晓1 小时前
第三十章 章节练习商品列表组件封装
前端·javascript·vue.js
fg_4112 小时前
无网络安装ionic和运行
前端·npm
理想不理想v2 小时前
‌Vue 3相比Vue 2的主要改进‌?
前端·javascript·vue.js·面试
酷酷的阿云2 小时前
不用ECharts!从0到1徒手撸一个Vue3柱状图
前端·javascript·vue.js
微信:137971205872 小时前
web端手机录音
前端
齐 飞2 小时前
MongoDB笔记01-概念与安装
前端·数据库·笔记·后端·mongodb