zoukankan      html  css  js  c++  java
  • vue中 表头 th 合并单元格,且表格列数不定的动态渲染方法

    吐槽

    今天,在vue中遇到 复杂表格的渲染 ,需要合并表头th的单元格,且合并单元格的那列的表头数据是动态数据,也就是不知道会有多少个表头列,而这几个表头列还分了好几个子表头

    这个需求在js里用Juicer模板很好做的,思路我是有的,但就是对于vue,我也算初学者,很多概念不是很懂,这就限制了思路。

    在网上搜了很多合并单元格的都是简单的数据合并,也就是td合并, 不是我们的需求,就不贴了。

    哎,废话不多说了,看代码吧:

    代码示例

    使用iviewuitable组件:

    最初,直接使用项目中的iviewuitable组件, 给 column 设置 children ,可以实现表头合并。先用写死的数据做了个样例,如下:

    <Table :columns="columns" :data="studentData" border></Table>

    data()中如下:

    
          columns: [
            {
              title: '序号',
               60,
              align: 'center',
              fixed: 'left',
              render: (h, params) => {
                return h('span', params.row._index + 1)
              }
            },
            {
              title: '姓名',
              key: 'name',
              align: 'center',
              fixed: 'left',
               80
            },
            {
              title: '学号',
              key: 'code',
              align: 'center',
               80
            },
            {
              title: '性别',
              key: 'sex',
              align: 'center',
               80
            },
            {
              title: '学期',
              key: 'term',
              align: 'center',
               80
            },
            {
              title: '9月28日',
              align: 'center',
              children: [
                {
                  title: '阅读',
                  key: 'date1_rScore',
                  align: 'center',
                  minWidth: 80,
                  sortable: true
                },
                {
                  title: '听力',
                  key: 'date1_lScore',
                  align: 'center',
                  minWidth: 80,
                  sortable: true
                },
                {
                  title: '写作',
                  key: 'date1_wScore',
                  align: 'center',
                  minWidth: 80,
                  sortable: true
                },
                {
                  title: '口语',
                  key: 'date1_sScore',
                  align: 'center',
                  minWidth: 80,
                  sortable: true
                },
                {
                  title: '总分',
                  key: 'date1_score',
                  align: 'center',
                  minWidth: 80,
                  sortable: true
                }
              ]
            },
            {
              title: '8月10日&14日',
              align: 'center',
              children: [
                {
                  title: '阅读',
                  key: 'date2_rScore',
                  align: 'center',
                  minWidth: 80,
                  sortable: true
                },
                {
                  title: '听力',
                  key: 'date2_lScore',
                  align: 'center',
                  minWidth: 80,
                  sortable: true
                },
                {
                  title: '写作',
                  key: 'date2_wScore',
                  align: 'center',
                  minWidth: 80,
                  sortable: true
                },
                {
                  title: '口语',
                  key: 'date2_sScore',
                  align: 'center',
                  minWidth: 80,
                  sortable: true
                },
                {
                  title: '总分',
                  key: 'date2_score',
                  align: 'center',
                  minWidth: 80,
                  sortable: true
                }
              ]
            },
            {
              title: '听力提高',
              key: 'lImprove',
              align: 'center',
               70
            },
            {
              title: '阅读提高',
              key: 'rImprove',
              align: 'center',
               70
            },
            {
              title: '写作提高',
              key: 'writingImprove',
              align: 'center',
               70
            },
            {
              title: '口语提高',
              key: 'sImprovem',
              align: 'center',
               70
            },
            {
              title: '总分提高',
              key: 'srImprove',
              align: 'center',
               70
            }
          ],
          studentData: [
            {
              name: 'xxx',
              code: '918989070065',
              sex: '男',
              term: '2018秋',
              date1: '9月28日',
              date1_rScore: '3.5',
              date1_lScore: '3.5',
              date1_wScore: '5',
              date1_sScore: '4',
              date1_score: '4',
              date2: '8月10日&14日',
              date2_rScore: '3.5',
              date2_lScore: '3.5',
              date2_wScore: '5',
              date2_sScore: '4',
              date2_score: '4',
              lImprove: '-0.5',
              rImprove: '0',
              wImprove: '1.5',
              sImprove: '0.5',
              srImprove: '0.5'
            }
          ],

    实现效果如图:
    图片描述

    重点是后端给的数据格式

    以下是data数据是后端接口返回的,其中的数据格式是这样的:

    [
        {
        "studentId": "ff808b937f50a33",
        "studentName": "傅xx",
        "studentCode": "91scdsc109",
        "sex": {
          "value": "MALE",
          "name": "男"
        },
        "termName": "2018秋",
        "examDates": [
          "10月",
          "9月28日"
        ],
        "map": {
          "9月28日": [
            {
              "courseName": "听力",
              "score": 6.0
            },
            {
              "courseName": "阅读",
              "score": 7.0
            },
            {
              "courseName": "写作",
              "score": 5.5
            }
          ]
        },
        "courseNames": [
          "听力",
          "阅读",
          "写作",
          "口语",
          "总分"
        ]
      },
      {
        "studentId": "ff80c52801bc",
        "studentName": "陈xx",
        "studentCode": "91edfedf3",
        "sex": {
          "value": "FEMALE",
          "name": "女"
        },
        "termName": "2018秋",
        "examDates": [
          "10月",
          "9月28日"
        ],
        "map": {
          "9月28日": [
            {
              "courseName": "听力",
              "score": 5.5
            },
            {
              "courseName": "阅读",
              "score": 6.0
            },
            {
              "courseName": "写作",
              "score": 5.5
            },
            {
              "courseName": "口语",
              "score": 5.5
            }
          ]
        },
        "courseNames": [
          "听力",
          "阅读",
          "写作",
          "口语",
          "总分"
        ]
      }
    ]
    

    重点是要以上述datamap里的日期为一组的表头,每组日期包含的是五门课,然后日期是根据数据库查出来的,不确定到底是几个日期,也就是table里这个日期的th是根据数据循环生成的,请仔细看这里给出的数据格式。

    使用H5的table实现

    template如下:

    
    <table class="table">
                <thead>
                        <tr>
                            <th rowspan="2">序号</th>
                            <th rowspan="2">姓名</th>
                            <th rowspan="2">学号</th>
                            <th rowspan="2">性别</th>
                            <th rowspan="2">学期</th>
                            <th colspan="5" v-for="(it,i) in examDates" :key="i">{{it}}</th>
                        </tr>
                        <tr>
                            <template v-for="itd in examDates">
                              <th v-for="(itc,j) in courseNames" :key="itd+j">{{itc}}</th>
                            </template>
                        </tr>
                </thead>
                <tbody>
                        <tr v-for="(item,index) in studentDataList" :key="index">
                            <td>{{index+1}}</td>
                            <td>{{item.studentName}}</td>
                            <td>{{item.studentCode}}</td>
                            <td>{{item.sex.name}}</td>
                            <td>{{item.termName}}</td>
                            <template v-for="examDate in examDates">
                              <template  v-for="(course,j) in courseNames">
                                <td :key="examDate+j">
                                  {{initScoreFinal(examDate,course,item.map)}}
                                </td>
                              </template>
                            </template>
                        </tr>
                </tbody>
              </table>

    获取到上述后端返回的数据后,对数据稍微处理下:

      data () {
        return {    
          studentDataList: [],
          examDates: [],
          courseNames: []
       },
       created () {
         this.getData ()
       },
       methods: {
        //    
        getData () {
          this.$get( //该方法是封装过的axios
            '/list.json',
            {
            ....//此处是参数,略
            },
            response => {
              this.examDates = response.data[0].examDates
              this.courseNames = response.data[0].courseNames 
              this.studentDataList = response.data
            }
          )
        },
        initScoreFinal (examDate, course, map) {
          let final = 0
          console.log('map:' + map)
          for (var it in map) {
            map[it].forEach((item, index, array) => {
              if (it === examDate && item.courseName === course) {
                final = item.score
              }
            })
          }
          return final
        }
    }
        

    效果如图:
    图片描述

    再吐个槽

    在网上搜了很多合并单元格的都是简单的数据合并,也就是td合并,
    我们这边的项目需要的这个表格比较变态,结合上述效果图来说吧,图中的表头是先按日期为一列th,这日期的列下分五门课程的子列th,且日期数目不定,可能是一两个日期,可能是多个日期,每个日期下对应的课程也不确定,就像学生上课,每天的课不同,但总共就那五门课,日期列的数目不定,课程数的数据不定,于是,这就很头疼了-_-||

    总之长知识了,记录下来。

    或许有大神能用iviewuitable组件 能做出来动态列数的表头合并,欢迎来一起谈论办法!!!

  • 相关阅读:
    Linux内核网络协议栈优化总纲
    Java实现 蓝桥杯VIP 算法训练 连续正整数的和
    Java实现 蓝桥杯VIP 算法训练 连续正整数的和
    Java实现 蓝桥杯VIP 算法训练 寂寞的数
    Java实现 蓝桥杯VIP 算法训练 寂寞的数
    Java实现 蓝桥杯VIP 算法训练 学做菜
    Java实现 蓝桥杯VIP 算法训练 学做菜
    Java实现 蓝桥杯VIP 算法训练 判断字符位置
    Java实现 蓝桥杯VIP 算法训练 判断字符位置
    Java实现 蓝桥杯VIP 算法训练 链表数据求和操作
  • 原文地址:https://www.cnblogs.com/10manongit/p/12744520.html
Copyright © 2011-2022 走看看