import Vue from 'vue' import common from '@/utils/common' export default { /** * 合并行与列 * @param cols 行与行之间合并的字段 * @param rows 行内合并的字段 * @param tableData 需要合并的table */ getData(cols, rows, tableData) { const loca = [] // 行间合并 const rowloca = [] // 行内合并 for (const k in rows) { rowloca.push({ rowSpan: 1, colSpan: 1, rowIndex: null, colIndex: null, colProperty: rows[k].name, value: null, getValue: rows[k].getValue }) } for (const j in cols) { loca.push({ rowSpan: 1, colSpan: 1, rowIndex: null, colIndex: null, colProperty: cols[j].name, order: 0, // 行序号 value: null, getValue: cols[j].getValue }) } // 行间合并 for (let i = 0; i < tableData.length; i++) { tableData[i].cellSpans = [] tableData[i].cellRowSpans = [] for (const _w in loca) { const w = loca[_w] if (i === 0 || w.value !== w.getValue(tableData[i])) { // 边界指针,1.第一条硬性第一个边界 2.与上一单元格值不同的属于边界 w.rowIndex = i // 行索引,若下一单元格值相同则以此索引叠加rowSpan值 w.rowSpan = 1 // rowSpan默认1 w.value = w.getValue(tableData[i]) // 单元格值 w.order += 1 // 行号+1 } else { // 若本单元格值==上一单元格值则合并列,rowSpan+=1 for (const p in tableData[w.rowIndex].cellSpans) { const n = tableData[w.rowIndex].cellSpans[p] if (n.colProperty === w.colProperty) { n.rowSpan += 1 } } } } tableData[i].cellSpans = common.deepCopy(loca) // 深度复制,否则总是指向最后一条数据 // 行内合并 for (let l = 0; l < rowloca.length; l++) { // 上一个单元格 const preRl = rowloca[l - 1] // 上一个单元格的数据 const preRlValue = preRl ? preRl.getValue(tableData[i]) : undefined // 当前单元格 const rl = rowloca[l] // 当前单元格的数据 const rlValue = rl.getValue(tableData[i]) if (l === 0 || !rlValue || preRlValue !== rlValue) { rl.rowSpan = 1 // rowSpan默认1 rl.colSpan = 1 } else { rl.rowSpan = 0 // rowSpan默认1 rl.colSpan = 0 // 若本单元格值==上一单元格值则列并列,colSpan+=1 for (let j = l; j > -1; j--) { if (tableData[i].cellRowSpans[j] && tableData[i].cellRowSpans[j].colSpan) { tableData[i].cellRowSpans[j].colSpan += 1 break } } } rl.rowIndex = i // 行索引,若下一单元格值相同则以此索引叠加rowSpan值 tableData[i].cellRowSpans.push(common.deepCopy(rl)) } } }, /** * 合并行、合并列 * @param row * @param column * @param rowIndex * @param columnIndex * @returns {{colspan: number, rowspan: (number|*)}|{colspan: number, rowspan: number}} */ mergeColRows({ row, column, rowIndex, columnIndex }) { // 遍历本行合并表 const spans = { rowspan: 1, colspan: 1 } for (const j in row.cellRowSpans) { const _c = row.cellRowSpans[j] // 列属性匹配 if (_c.colProperty === column.property) { // 若合并表指向本单元格则构建合并参数并返回 if (_c.rowIndex === rowIndex) { spans.colspan = _c.colSpan } break } } // 行间合并 for (const i in row.cellSpans) { const _r = row.cellSpans[i] // 列属性匹配 if (_r.colProperty === column.property) { // 若合并表指向本单元格则构建合并参数并返回 if (_r.rowIndex === rowIndex) { spans.rowspan = _r.rowSpan } else { // 否则隐藏该单元格。这里必须有,否则单元格会被右移一列 spans.rowspan = 0 } } } return spans }, /** * 添加行 * @param tableData$refs 表 * @param row 默认行数据,如果C1为true,那么则将C1的数值转换为索引值;如果不给则默认为{} */ addRow(tableData$refs, row) { if (!row) { // 如果没有给出每行默认值时 row = {} } row.index = tableData$refs.data.length if (row.C1) { tableData$refs.columns.some((v) => { if (v.property && v.type === 'index') { row[v.property] = tableData$refs.data.length + 1 return true } }) } tableData$refs.data.push(row) setTimeout(() => { tableData$refs.setCurrentRow(row) }, 10) // 用于延时渲染后选中这行 }, /** * 删除行(需要保证每一行都有一个index属性) * 建议使用方法:index列要有这个属性 :index="indexMethod" * 建议方法内容: * indexMethod(index) { this.tableData[index].index = index return (index + 1) } * @param tableData$refs 表 */ delRow(tableData$refs) { if (tableData$refs.selection.length === 0) { Vue.prototype.$message({ message: '请选中需要删除的数据!', type: 'error' }) } else { tableData$refs.selection.sort((a, b) => { return a.index - b.index }) for (let i = tableData$refs.selection.length; i > 0; i--) { tableData$refs.data.splice(tableData$refs.selection.pop().index, 1) } tableData$refs.clearSelection() } } }