今天,在vue
中遇到 複雜表格的渲染 ,須要合併表頭th
的單元格,且合併單元格的那列的表頭數據是動態數據,也就是不知道會有多少個表頭列,而這幾個表頭列還分了好幾個子表頭
。vue
這個需求在js裏用Juicer模板很好作的,思路我是有的,但就是對於vue
,我也算初學者,不少概念不是很懂,這就限制了思路。ios
在網上搜了不少合併單元格的都是簡單的數據合併,也就是td
合併, 不是咱們的需求,就不貼了。git
哎,廢話很少說了,看代碼吧:github
iviewui
的table
組件:最初,直接使用項目中的iviewui
的table
組件, 給 column 設置 children ,能夠實現表頭合併。先用寫死的數據作了個樣例,以下:數據庫
<Table :columns="columns" :data="studentData" border></Table>
data()中以下:json
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' } ],
實現效果如圖:axios
如下是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是根據數據循環生成的,請仔細看這裏給出的數據格式。iview
template以下:ui
<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
組件 能作出來動態列數的表頭合併,歡迎來一塊兒談論辦法!!!