效果圖:
需求:
1.相同的項目要合並,相同的項目下相同塔樓要合並
2.日期動態生成(需判斷跨年跨月)
3.列合並代表工作時長(顏色代表狀態)
邏輯:
1.先處理表頭,日期項自定義key值,如果跨年的話,添加一個子項(跨月一樣),用三元表達式自定義class顏色
2.跟后端協商,項目,塔樓和日期都要返回一個總和值回來,然后根據這個值去指定合並(因為手動判斷合並頁面渲染會很慢,數據多時會死機)
代碼:
1.初始化表頭:
columns: [ { title: '項目', key: 'taskItem', fixed: 'left', align: 'center', width: 200 }, { title: '塔樓', key: 'taskArea', fixed: 'left', align: 'center', width: 120 } ],
2.當數據回來時,表頭處理
日期是兩層結構,所以不同年和同月要push一個對象,而具體的日期在.children里
日期格式:["7-6", "7-7", "7-8", "7-9", "7-10", "7-11", "7-13", "7-14", "7-15", "7-16", "7-17", "7-18", "7-20", "7-21"]
columnsDate () { // let starttime = this.$route.query.schStartdate // let endtime = this.$route.query.schEnddate let starttime = this.schInfo.schStartdate let endtime = this.schInfo.schEnddate // '2020-06-29' // this.schInfo.schEnddate // 開始時間的年/月/日 let startArr = starttime.split('-')
// 結束時間 let endArr = endtime.split('-') // 同年 if (startArr[0] === endArr[0]) { // 同月 if (startArr[1] === endArr[1]) { // console.log('同月') let columnsObj = { title: '', align: 'center', children: [] } columnsObj.title = `${startArr[0]}年${startArr[1]}月` for (var i = 0; i < this.dayData.length; i++) { // let columnStyle = isWeekend(startArr[0], startArr[1], i) ? 'weekend-style' : '' let startMonth = this.dayData[i].split('-')[0] let day = this.dayData[i].split('-')[1] let objItem = { title: `${this.dayData[i].split('-')[1]}號`, key: `Y${startArr[0]}M${startMonth}D${day}`, // 根據key賦值 align: 'center', minWidth: 90, className: 'weekend-style', render: (h, params) => { return h('div', { // 1:未派發,2.已派發,3已完成) 自定義顏色 class: params.row.state === 3 && params.row[`Y${startArr[0]}M${startMonth}D${day}`] !== '-' ? 'span-mouse-on2' : params.row.state === 2 && params.row[`Y${startArr[0]}M${startMonth}D${day}`] !== '-' ? 'span-mouse-on' : params.row.state === 1 && params.row[`Y${startArr[0]}M${startMonth}D${day}`] !== '-' ? 'span-mouse-on1' : '', on: { click: () => { this.showDetail(params, params.row[`Y${startArr[0]}M${startMonth}D${day}`]) } } }, params.row[`Y${startArr[0]}M${startMonth}D${day}`]) } } columnsObj.children.push(objItem) } // this.BiweeklyPlanTable.columns.push(columnsObj) this.columns.push(columnsObj) } else { // console.log('不同月') for (var f = 0; f < endArr[1] - startArr[1] + 1; f++) { let columnsObj = { title: '', align: 'center', children: [] } var Month = parseInt(startArr[1]) + f Month = Month < 10 ? '0' + Month : Month columnsObj.title = `${startArr[0]}年${Month}月` for (var l = 0; l < this.dayData.length; l++) { // let columnStyle = isWeekend(startArr[0], startArr[1], i) ? 'weekend-style' : '' if (this.dayData[l].split('-')[0] === parseInt(Month) + '') { let startMonth = this.dayData[l].split('-')[0] let day = this.dayData[l].split('-')[1] let objItem = { title: `${this.dayData[l].split('-')[1]}號`, key: `Y${startArr[0]}M${startMonth}D${day}`, align: 'center', minWidth: 90, className: 'weekend-style', render: (h, params) => { return h('div', { // 1:未派發,2.已派發,3已完成) class: params.row.state === 3 && params.row[`Y${startArr[0]}M${startMonth}D${day}`] !== '-' ? 'span-mouse-on2' : params.row.state === 2 && params.row[`Y${startArr[0]}M${startMonth}D${day}`] !== '-' ? 'span-mouse-on' : params.row.state === 1 && params.row[`Y${startArr[0]}M${startMonth}D${day}`] !== '-' ? 'span-mouse-on1' : '', on: { click: () => { this.showDetail(params) } } }, params.row[`Y${startArr[0]}M${startMonth}D${day}`]) } } columnsObj.children.push(objItem) } } this.columns.push(columnsObj) } } } // console.log(this.dayData) // console.log(this.columns, '表頭') // console.log(this.newData, '內容') },
3.初始化渲染表格數據
// 拿到日期的數組循環遍歷成表頭key值那樣賦值‘—’,再push進data里 getForData () { // console.log(this.columnsLength, length)this.schInfo.schStartdate let starttime = this.schInfo.schStartdate.split('-')[0] var obj = {} for (var i = 0; i < this.dayData.length; i++) { var day = 'Y' + starttime + 'M' + this.dayData[i].split('-')[0] + 'D' + this.dayData[i].split('-')[1] obj[day] = '-' } return obj },
4.最終表格數據 // 數據處理
getBiweeklyPlanDate () { this.newData = [] let dataArr = this.data dataArr.forEach(arriItem => { let newObj = this.getForData() newObj.taskItem = arriItem.schTask.taskItem newObj.taskArea = arriItem.schTask.taskArea newObj.state = arriItem.schTask.state newObj.schTaskId = arriItem.schTask.id newObj.mergeCol = arriItem.itemsum ? arriItem.itemsum : 0 newObj.areanum = arriItem.areanum ? arriItem.areanum : 0 var dt = arriItem.schTask.dateRange.split(',') newObj.long = dt.length let startArr = arriItem.schTask.planStartDate.split('-') // 開始時間 planStartDate: "2020-07-06" // let startArr = dayLis.split('-') let startYear = startArr[0] let startMonth = startArr[1] startMonth = startMonth[0] === '0' ? startMonth.replace('0', '') : startMonth let startDay = startArr[2] startDay = startDay[0] === '0' ? startDay.replace('0', '') : startDay let startKey = `Y${startYear}M${startMonth}D${startDay}` newObj[startKey] = arriItem.schTask.state === 3 ? `${arriItem.schTask.taskFloor}(已完成)` : arriItem.schTask.taskFloor // 賦值 this.dayData.forEach((day, index) => { if (day === `${startMonth}-${startDay}`) { // 記住是哪一列,合並列時要用到 newObj.i = index + 2 } }) this.newData.push(newObj) }) },
5.合並(最重要代碼)
// html <Table :columns="columns" :data="newData" border :span-method="handleSpan"></Table> // js // 表格的合並單元格處理 handleSpan ({ row, column, rowIndex, columnIndex }) { if (columnIndex === 0) { // 計算合並的行數列數 let x = row.mergeCol === 0 ? 0 : row.mergeCol let y = row.mergeCol === 0 ? 0 : 1 // console.log(x , y) return [x, y] } if (columnIndex === 1) { // 計算合並的行數列數 let x = row.areanum === 0 ? 0 : row.areanum let y = row.areanum === 0 ? 0 : 1 // console.log(x , y) return [x, y] } // 列合並 if (columnIndex === row.i) { return [1, row.long] } else if (columnIndex > row.i && columnIndex < row.i + row.long) { return [0, 0] } },
謙虛的小白望能得到大神的指導~