|
|
|
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()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|