You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

179 lines
5.7 KiB

3 years ago
import Vue from 'vue'
import common from '@/utils/common'
export default {
/**
* 合并行与列
* @param cols 行与行之间合并的字段
* @param rows 行内合并的字段
* @param tableData 需要合并的table
*/
3 years ago
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}}
*/
3 years ago
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的数值转换为索引值如果不给则默认为{}
*/
3 years ago
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
*/
3 years ago
delRow(tableData$refs) {
if (tableData$refs.selection.length === 0) {
Vue.prototype.$message({
message: '请选中需要删除的数据!',
type: 'error'
})
} else {
for (let i = 0; i < tableData$refs.selection.length; i++) {
const index = tableData$refs.data.indexOf(tableData$refs.selection[i])
tableData$refs.data.splice(index, 1)
}
for (let i = 0; i < tableData$refs.data.length; i++) {
tableData$refs.data[i].index = i + 1
3 years ago
}
tableData$refs.clearSelection()
}
}
}