本文介绍: Element-UI组件eltable用于展示多条结构类似的数据,可对数据进行排序筛选、对比或其他自定义操作这里使用到以下两项,来完成今天demo演示:1. 多级表头数据结构比较复杂时候,可使用多级表头来展现数据的层次关系。2. 合并行或列多行多列共用一个数据时,可以合并行或列

Element-UI组件eltable用于展示多条结构类似的数据,可对数据进行排序筛选、对比或其他自定义操作

使用到以下两项,来完成今天demo演示

  1. 多级表头数据结构比较复杂时候,可使用多级表头来展现数据的层次关系

  1. 合并行或列多行多列共用一个数据时,可以合并行或列

官方文档地址https://element.eleme.cn/#/zh-CN/component/table

需要实现表格下图

一、安装elementui

使用npm进行安装

npm i element-ui -S

二、表头实现

这里表头实现比较简单代码如下

<template>
  <div>
    <el-table :data="tableStudentData" :span-method="reconstructionStuCell" style="width: 100%"&gt;
      <el-table-column type="index" label="序号" width="50"&gt;</el-table-column&gt;
      <el-table-column prop="name" label="姓名" width="80"&gt;</el-table-column&gt;
      <el-table-column label="科目信息"&gt;
        <el-table-column prop="courseName" label="科目" width="80"></el-table-column>
        <el-table-column prop="date" label="日期" width="80"></el-table-column>
        <el-table-column prop="timeStr" label="考试时间" width="100"></el-table-column>
      </el-table-column>
      <el-table-column label="成绩信息">
        <el-table-column prop="score" label="成绩" width="60"></el-table-column>
        <el-table-column prop="scoreTotal" label="总分" width="60"></el-table-column>
        <el-table-column prop="total" label="满分" width="60"></el-table-column>
        <el-table-column prop="totalAll" label="满分总分" width="100">
          <template slot-scope="scope">
            <span v-if="scope.row.totalAll">{{scope.row.totalAll}} (及格率:{{parseInt(scope.row.scoreTotal/scope.row.totalAll*100)}}%)</span>
          </template>
        </el-table-column>
      </el-table-column>
    </el-table>
    
  </div>
</template>

<script>
  export default {
    data(){
      return {
        tableData: [],
        tableStudentData: []
      }
    },
    created() {
 
    },
    methods: {
      /**
       * 合并单元格数据
       */
      reconstructionStuCell({ row, column, rowIndex, columnIndex }){
        
      }
      //end
    }
  }
</script>

<style lang="scss">

</style>

此时表头效果已形成,如下图

三、数据渲染

数据渲染这里较为复杂这里为方便大家理解,进行逐步拆解叙述。如有更好方法,也欢迎大家指点。

3.1 模拟数据

如上图,在element-table目录中,新建data.js文件用于存储模拟数据,代码如下

export const studentData = [
  {name: "李四", subject: [
    {courseName: "语文", date: "20日", timeStr: "09:00~11:30", score: 90, total: 150},
    {courseName: "政治", date: "20日", timeStr: "14:30~16:30", score: 70, total: 100},
    {courseName: "数学", date: "21日", timeStr: "09:00~11:30", score: 100, total: 150},
    {courseName: "历史", date: "21日", timeStr: "14:30~16:30", score: 72, total: 100},
    {courseName: "英语", date: "22日", timeStr: "09:00~11:30", score: 95, total: 150},
  ]},
  {name: "王五", subject: [
    {courseName: "语文", date: "20日", timeStr: "09:00~11:30", score: 85, total: 150},
    {courseName: "政治", date: "20日", timeStr: "14:30~16:30", score: 60, total: 100},
    {courseName: "数学", date: "21日", timeStr: "09:00~11:30", score: 90, total: 150},
    {courseName: "历史", date: "21日", timeStr: "14:30~16:30", score: 68, total: 100},
    {courseName: "英语", date: "22日", timeStr: "09:00~11:30", score: 75, total: 150},
  ]},
  {name: "小美", subject: [
    {courseName: "语文", date: "20日", timeStr: "09:00~11:30", score: 120, total: 150},
    {courseName: "政治", date: "20日", timeStr: "14:30~16:30", score: 85, total: 100},
    {courseName: "数学", date: "21日", timeStr: "09:00~11:30", score: 120, total: 150},
    {courseName: "历史", date: "21日", timeStr: "14:30~16:30", score: 80, total: 100},
    {courseName: "英语", date: "22日", timeStr: "09:00~11:30", score: 130, total: 150},
  ]}
];

页面引入模拟数据,并赋值表格变量代码如下

<script>
  import { studentData } from './data.js'
  export default {
    data(){
      return {
        tableStudentData: studentData
      }
    },
    created() { },
    methods: {
      /**
       * 合并单元格数据
       */
      reconstructionStuCell({ row, column, rowIndex, columnIndex }){
        
      }
      //end
    }
  }
</script>

此时表格中可以正常渲染部分数据了,效果图如下

3.2 数据处理

如上图发现,科目和成绩相关信息,未显示出来。这里需要对数据进行处理下,将所有科目信息调整到 和姓名字段为同一行数据中。需要做以下几步:

  1. 将subject级数据全部移至name同级的同一行数据中。

  1. name字段原数据移至subject第一行数据中;item和sub进行合并

  1. 无subject子项数据的,保持原数据输出

data.js中,添加重构数据reconstructionStuData()函数代码如下

/**
 * 重构学生数据 并返回
 */
export const reconstructionStuData = data => {
  if(!Array.isArray(data)) return [];

  let tmpData = [];
  data.forEach((item, i) => {
    //有二级数据的进行处理
    if(Array.isArray(item.subject)&amp;&amp;item.subject.length>0){
      //循环成绩
      item.subject.forEach((sub, j) => {
        let subData = {};
        if(j==0){
          //子项第一行数据,和姓名信息同行
          subData = Object.assign({ }, item, sub);
        }
        //其他行数据无须添加名字信息第一行数据会合并结束位置填充后也会被覆盖else{
          subData = Object.assign({ }, sub);
        }
        //if end
        tmpData.push( subData );
      });
    }
    //subject无子项数据,保留当前位置输出
    else{
      tmpData.push(
        Object.assign({ }, item)
      );
    }
  });

  return tmpData;
}

引入reconstructionStuData()函数代码如下

<script>
  import { reconstructionStuData, studentData } from './data.js'
  export default {
    data(){
      return {
        tableStudentData: studentData
      }
    },
    created() {
      this.tableStudentData = reconstructionStuData(studentData);
    },
    methods: {
      /**
       * 合并单元格数据
       */
      reconstructionStuCell({ row, column, rowIndex, columnIndex }){
        
      }
      //end
    }
  }
</script>

此时表格效果图如下

3.4 图解

如上图

这是我们发现methods定义的reconstructionStuCell()函数还未使用,通过给table传入span-method方法可以实现合并行或列方法参数是一个对象里面包含当前行row、当前列column、当前行号rowIndex、当前列号columnIndex四个属性。该函数可以返回一个包两个元素数组第一个元素代表rowspan,第二个元素代表colspan。 也可以返回一个键名为rowspan和colspan对象

span-method相当于从数据单元格第一行开始,每行每列开始循环执行,想当于 9 * 15 执行135次,通过函数中 rowIndex, columnIndex字段进行判断当前循环是哪行哪列,并作对应处理

这里我们添加以下逻辑,在每行数据中添加姓名、总分,满分总分对应columnIndex1、columnIndex6、columnIndex8字段,用来存储需要返回colspan和rowspan数据,代码如下:

reconstructionStuCell({ row, column, rowIndex, columnIndex }){
    let column1Data = row['columnIndex1'];
    let column6Data = row['columnIndex6'];
    let column8Data = row['columnIndex8'];

    //判断条件满足情况下,返回对应的rowspan和colspan数据
    if(
      (column1Data&amp;&amp;column1Data.columnIndex==columnIndex) ||      //姓名组合并
      (column6Data&amp;&amp;column6Data.columnIndex==columnIndex) ||      //总分组合并
      column8Data&amp;&amp;column8Data.columnIndex==columnIndex           //满分总分组合并
    ){
      return row['columnIndex'+columnIndex];
    }
    //if end
  }

比如执行span-method方法时,此时获取row数据中columnIndex1,columnIndex1中的columnIndex值为1,与span-method方法中columnIndex进行对比。

1、此时每行中列1都会被匹配到,列1行1返回{colspan: 1, rowspan: 5},则往下合并5个单元格

2、列1行2返回{colspan: 0, rowspan: 0},则单元格渲染,否则此行多一个单元格会错位;

3、列1行3,列1行4…… 同理。

列6(总分)、列8(满分总分)同理,通过columnIndex6和columnIndex8进行判断,进行单元格合并。

以上代码添加后,发现表格并无任何变化,这是因为重构数据函数中,还未添加对应的columnIndex1、columnIndex6、columnIndex8字段。

3.5 合并列 – 姓名

首先,我们来合并(姓名)这列数据,将每行数据中添加columnIndex1,子属性变量columnIndex表示合并对应的列位置。

subject有子项数据除第一行数据,后面所有rowspan和colspan为0,第1个单元往下合并后,会填充其他行空缺位置。

subject无子项数据rowspan和colspan为1,保留原位置渲染。如为0则当前单元格不被渲染,表格会错乱

代码如下:

export const reconstructionStuData = data => {
  if(!Array.isArray(data)) return [];

  let tmpData = [];
  data.forEach((item, i) => {
    //有二级数据的进行处理
    if(Array.isArray(item.subject)&amp;&amp;item.subject.length>0){
      //循环成绩
      item.subject.forEach((sub, j) => {
        let subData = {};
        if(j==0){
          //子项第一行数据,和姓名信息同行
          subData = Object.assign({ columnIndex1: { columnIndex: 1, rowspan: item.subject.length, colspan: 1 } }, item, sub);
        }
        //其他行数据无须添加 姓名字段信息(第一行数据会合并到结束位置,填充后也会被覆盖else{
          subData = Object.assign({ columnIndex1: { columnIndex: 1, rowspan: 0, colspan: 0 } }, sub);
        }
        //if end
        tmpData.push( subData );
      });
    }
    //无子项数据,保留当前位置输出
    else{
      tmpData.push(
        Object.assign({ columnIndex1: { columnIndex: 1, rowspan: 1, colspan: 1 } }, item)
      );
    }
  });

  return tmpData;
}

此时大家看到表格的(姓名)列,已合并到对应长度效果图如下:

3.6 合并列 – 总分和满分总分

总分和满分总分合并部分,和(姓名)列同理,但多出一步则需计算出对应科目的总分 和 所有科目的满分总分。

增加第6列和第8列合并数据columnIndex6和columnIndex8,并新增scoreTotal和totalAll分别保存总分和满分总分结果

代码如下:

export const reconstructionStuData = data => {
  if(!Array.isArray(data)) return [];

  let tmpData = [];
  data.forEach((item, i) => {
    //有二级数据的进行处理
    if(Array.isArray(item.subject)&amp;&amp;item.subject.length>0){
      //循环成绩
      item.subject.forEach((sub, j) => {
        let subData = {};
        if(j==0){
          //子项第一行数据,和姓名信息同行
          subData = Object.assign({ columnIndex1: { columnIndex: 1, rowspan: item.subject.length, colspan: 1 } }, item, sub);

          //计算总分
          subData['scoreTotal'] = item.subject.reduce((total, value) => {
            return total + value.score;
          }, 0);
          subData['columnIndex6'] = { columnIndex: 6, rowspan: item.subject.length, colspan: 1 };
          //计算满分总分
          subData['totalAll'] = item.subject.reduce((total, value) => {
            return total + value.total;
          }, 0);
          subData['columnIndex8'] = { columnIndex: 8, rowspan: item.subject.length, colspan: 1 };
        }
        //其他行数据无须添加 姓名字段信息(第一行数据会合并到结束位置,填充后也会被覆盖)
        else{
          subData = Object.assign({ columnIndex1: { columnIndex: 1, rowspan: 0, colspan: 0 } }, sub);

          //总分和满分总分 被合并部分单元填写为0
          subData['columnIndex6'] = { columnIndex: 6, rowspan: 0, colspan: 0 };
          subData['columnIndex8'] = { columnIndex: 8, rowspan: 0, colspan: 0 };
        }
        //if end
        tmpData.push( subData );
      });
    }
    //无子项数据,保留当前位置输出
    else{
      tmpData.push(
        Object.assign({ columnIndex1: { columnIndex: 1, rowspan: 1, colspan: 1 } }, item)
      );
    }
  });

  return tmpData;
}

此时,咱们需要的表格就被渲染出来了,如下图

3.7 span-method优化

reconstructionStuCell()函数中对列的合并参数一一取出,这样会比较繁琐,通过for循环对row行内数据进行查询,并通过columnIndex判断对应列及返回结果。代码如下:

reconstructionCell({ row, column, rowIndex, columnIndex }){
    for(var key in row){
     //匹配列数据
     if(/columnIndex/.test(key)&amp;&amp;'undefined'!==typeof row[key]['columnIndex']){
       //关联对应列,并返回合并参数
       if(row[key].columnIndex == columnIndex){
         return {
           rowspan: row[key].rowspan,
           colspan: row[key].colspan
         }
       }
     }
    }
}

这里reconstructionStuData()函数处理能力还是相对不足,只能处理特定的表格合并。希望对大家有所帮助,仅供大家参考

原文地址:https://blog.csdn.net/jiciqiang/article/details/129426471

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_26554.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注