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组件 能做出来动态列数的表头合并,欢迎来一起谈论办法!!!

    来源:https://segmentfault.com/a/1190000016895856

  • 相关阅读:
    全国省市县三级数据库
    多源教学数据管理系统之团队课设博客
    1.判断字符串中的字符是否Unique
    [转载]linux防火墙基础和管理设置iptables规则
    (转)Sed使用详解
    2.判断回文(Anagrams)
    【转载】关于23 种设计模式的有趣见解
    macbook M1芯片在centos8下安装k8s笔记
    Winform 学习初级 从WebForm到WinForm
    如何建立数据模型
  • 原文地址:https://www.cnblogs.com/lovellll/p/10125963.html
Copyright © 2011-2022 走看看