1. 程式人生 > >vue中 表頭 th 合並單元格,且表格列數不定的動態渲染方法

vue中 表頭 th 合並單元格,且表格列數不定的動態渲染方法

value 數據 5.5 lis 初學 代碼 課程 復雜 比較

吐槽

今天,在vue中遇到 復雜表格的渲染 ,需要合並表頭th的單元格,且合並單元格的那列的表頭數據是動態數據,也就是不知道會有多少個表頭列,而這幾個表頭列還分了好幾個子表頭

這個需求在js裏用Juicer模板很好做的,思路我是有的,但就是對於vue,我也算初學者,很多概念不是很懂,這就限制了思路。

在網上搜了很多合並單元格的都是簡單的數據合並,也就是td合並, 不是我們的需求,就不貼了。

哎,廢話不多說了,看代碼吧:

代碼示例

使用iviewuitable組件:

最初,直接使用項目中的iviewuitable組件, 給 column 設置 children ,可以實現表頭合並。先用寫死的數據做了個樣例,如下:


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

data()中如下:



      columns: [
        {
          title: ‘序號‘,
          width: 60,
          align: ‘center‘,
          fixed: ‘left‘,
          render: (h, params) => {
            return h(‘span‘, params.row._index + 1)
          }
        },
        {
          title: ‘姓名‘,
          key: ‘name‘,
          align: ‘center‘,
          fixed: ‘left‘,
          width: 80
        },
        {
          title: ‘學號‘,
          key: ‘code‘,
          align: ‘center‘,
          width: 80
        },
        {
          title: ‘性別‘,
          key: ‘sex‘,
          align: ‘center‘,
          width: 80
        },
        {
          title: ‘學期‘,
          key: ‘term‘,
          align: ‘center‘,
          width: 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‘,
          width: 70
        },
        {
          title: ‘閱讀提高‘,
          key: ‘rImprove‘,
          align: ‘center‘,
          width: 70
        },
        {
          title: ‘寫作提高‘,
          key: ‘writingImprove‘,
          align: ‘center‘,
          width: 70
        },
        {
          title: ‘口語提高‘,
          key: ‘sImprovem‘,
          align: ‘center‘,
          width: 70
        },
        {
          title: ‘總分提高‘,
          key: ‘srImprove‘,
          align: ‘center‘,
          width: 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

vue中 表頭 th 合並單元格,且表格列數不定的動態渲染方法