vue中 表頭 th 合並單元格,且表格列數不定的動態渲染方法
吐槽
今天,在vue
中遇到 復雜表格的渲染 ,需要合並表頭th
的單元格,且合並單元格的那列的表頭數據是動態數據,也就是不知道會有多少個表頭列,而這幾個表頭列還分了好幾個子表頭
。
這個需求在js裏用Juicer模板很好做的,思路我是有的,但就是對於vue
,我也算初學者,很多概念不是很懂,這就限制了思路。
在網上搜了很多合並單元格的都是簡單的數據合並,也就是td
合並, 不是我們的需求,就不貼了。
哎,廢話不多說了,看代碼吧:
代碼示例
使用iviewui
的table
組件:
最初,直接使用項目中的iviewui
的table
組件, 給 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": [ "聽力", "閱讀", "寫作", "口語", "總分" ] } ]
重點是要以上述data
中map
裏的日期
為一組的表頭,每組日期包含的是五門課,然後日期是根據數據庫查出來的,不確定到底是幾個日期
,也就是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
,且日期數目不定,可能是一兩個日期,可能是多個日期,每個日期下對應的課程也不確定,就像學生上課,每天的課不同,但總共就那五門課,日期列的數目不定,課程數的數據不定,於是,這就很頭疼了-_-||
總之長知識了,記錄下來。
或許有大神能用iviewui
的table
組件 能做出來動態列數的表頭合並,歡迎來一起談論辦法!!!
來源:https://segmentfault.com/a/1190000016895856
vue中 表頭 th 合並單元格,且表格列數不定的動態渲染方法