文章需求:动态实现table表格中行/列的自动合并
使用框架及UI类库:Vue+Element-ui
代码地址:https://github.com/dreamITGirl/VueProgect
最终实现的表格数据
实现思路:
在table组件中,提供了一个属性:span-method,它是一个Function,本身有4个参数,分别是row,rowIndex,colum,columIndex;这四个值可以直接拿到。先处理连续相同的列的值,做标记,然后,在合并的方法中,根据我们处理好的数组,去对应的合并行或列
实现代码:
//处理table数据的方法,将连续相同的数据汇总
merge() {
let OrderObj = {};
let provinceObj = {};
this.tableData.forEach((element, index) => {
element.rowIndex = index;
if (OrderObj[element.operators]) {
//如果下一个数据中的operators和这一列的数据相同,则合并,反之,不合并;(增加这一个判断的目的是为了防止隔行出现相同时,列合并)
let nextItem = this.tableData[index + 1].operators
? this.tableData[index + 1].operators
: undefined;
let prevItem = this.tableData[index - 1].operators
? this.tableData[index - 1].operators
: undefined;
if (element.operators == nextItem) {
OrderObj[element.operators].push(index);
} else if (element.operators == prevItem) {
OrderObj[element.operators].push(index);
}
} else {
OrderObj[element.operators] = [];
OrderObj[element.operators].push(index);
}
if (provinceObj[element.province]) {
let nextPro = this.tableData[index + 1]
? this.tableData[index + 1].province
: undefined;
let prevPro = this.tableData[index - 1].province
? this.tableData[index - 1].province
: undefined;
if (element.province == nextPro) {
provinceObj[element.province].push(index);
} else if (element.province == prevPro) {
provinceObj[element.province].push(index);
}
} else {
provinceObj[element.province] = [];
provinceObj[element.province].push(index);
}
});
// 将数组长度大于1的值 存储到this.OrderIndexArr(也就是需要合并的项)
for (let k in OrderObj) {
if (OrderObj[k].length > 1) {
this.OrderIndexArr.push(OrderObj[k]);
}
}
for (let i in provinceObj) {
if (provinceObj[i].length > 1) {
this.provinceArr.push(provinceObj[i]);
}
}
}
//合并的方法
objectSpanMethod({ row, rowIndex, column, columnIndex }) {
if (columnIndex === 0) {
for (let i = 0; i < this.OrderIndexArr.length; i++) {
let element = this.OrderIndexArr[i];
for (let j = 0; j < element.length; j++) {
let item = element[j];
if (rowIndex === item) {
if (j === 0) {
return {
rowspan: element.length,
colspan: 1
};
} else if (j !== 0) {
return {
rowspan: 0,
colspan: 0
};
}
}
}
}
}
//因为需求是前两列中有相同的就合并,所以需要再次判断出来第一列中哪些行需要合并;
if (columnIndex === 1) {
for (let j = 0; j < this.provinceArr.length; j++) {
let element = this.provinceArr[j];
for (let k = 0; k < element.length; k++) {
let item = element[k];
if (rowIndex === item) {
if (k === 0) {
return {
rowspan: element.length,
colspan: 1
};
} else if (k !== 0) {
return {
rowspan: 0,
colspan: 0
};
}
}
}
}
}
}
=============================================
上面的代码会导致一个问题,就是当上述数据中,当运营商是移动时,且也有省份和其他运营商的省份出现相同且连续时,即table的数据如下时,也就是移动中有和其他的省份出现相同且连续的时候,代码算法就会出现问题。这时算出的出现广州的数组位置index数组就是[0,1,2,8,9],这样的话,table的合并行就会出现错误。后面是修改后的代码
tableData: [
{
operators: "其他",
province: "广东",
room: "广州双线1",
abbreviation: "GZ_DB2",
bandwidth: "10G",
flow:
"第一条1G (no latest data,no latest data)第二条1G (no latest data,no latest data)"
},
{
operators: "其他",
province: "广东",
room: "广州双线2",
abbreviation: "GZ_DB2",
bandwidth: "10G",
flow:
"第一条1G (no latest data,no latest data)第二条1G (no latest data,no latest data)"
},
{
operators: "其他",
province: "广东",
room: "广州双线3",
abbreviation: "GZ_DB2",
bandwidth: "10G",
flow:
"第一条1G (no latest data,no latest data)第二条1G (no latest data,no latest data)"
},
{
operators: "电信",
province: "浙江",
room: "广州双线2",
abbreviation: "GZ_DB2",
bandwidth: "10G",
flow:
"第一条10G (no latest data,no latest data) 第二条10G (no latest data,no latest data) 第三条10G (no latest data,no latest data) 第四条10G"
},
{
operators: "电信",
province: "浙江",
room: "杭州双线2",
abbreviation: "GZ_DB2",
bandwidth: "10G",
flow:
"第一条10G (no latest data,no latest data) 第二条10G (no latest data,no latest data) 第三条10G (no latest data,no latest data) 第四条10G"
},
{
operators: "电信",
province: "浙江",
room: "杭州双线2",
abbreviation: "GZ_DB2",
bandwidth: "10G",
flow:
"第一条10G (no latest data,no latest data) 第二条10G (no latest data,no latest data) 第三条10G (no latest data,no latest data) 第四条10G"
},
{
operators: "联通",
province: "江西",
room: "杭州双线2",
abbreviation: "GZ_DB2",
bandwidth: "10G",
flow:
"第一条1G (no latest data,no latest data)第二条1G (no latest data,no latest data)"
},
{
operators: "联通",
province: "浙江",
room: "浙江双线2",
abbreviation: "GZ_DB2",
bandwidth: "10G",
flow:
"第一条10G (no latest data,no latest data) 第二条10G (no latest data,no latest data) 第三条10G (no latest data,no latest data) 第四条10G"
},
{
operators: "移动",
province: "江西",
room: "江西双线2",
abbreviation: "GZ_DB2",
bandwidth: "10G",
flow:
"第一条1G (no latest data,no latest data)第二条1G (no latest data,no latest data)"
},
{
operators: "移动",
province: "广东",
room: "广州双线2",
abbreviation: "GZ_DB2",
bandwidth: "10G",
flow:
"第一条1G (no latest data,no latest data)第二条1G (no latest data,no latest data)"
},
{
operators: "移动",
province: "广东",
room: "广州双线2",
abbreviation: "GZ_DB2",
bandwidth: "10G",
flow:
"第一条1G (no latest data,no latest data)第二条1G (no latest data,no latest data)"
},
{
operators: "移动",
province: "广东",
room: "广州双线2",
abbreviation: "GZ_DB2",
bandwidth: "10G",
flow:
"第一条1G (no latest data,no latest data)第二条1G (no latest data,no latest data)"
},
]
merge() {
let OrderObj = {};
let provinceObj = {};
this.tableData.forEach((element, index) => {
element.rowIndex = index;
if (OrderObj[element.operators]) {
let nextItem = this.tableData[index + 1] //为防止报错,先判断this.tableData[index+1]项是否存在,否则js会报错
? this.tableData[index + 1].operators
: undefined;
let prevItem = this.tableData[index - 1].operators
? this.tableData[index - 1].operators
: undefined;
if (element.operators == nextItem) {
OrderObj[element.operators].push(index);
} else if (element.operators == prevItem) {
OrderObj[element.operators].push(index);
}
} else {
OrderObj[element.operators] = [];
OrderObj[element.operators].push(index);
}
if (provinceObj[element.province]) {
let nextPro = this.tableData[index + 1]
? this.tableData[index + 1].province
: undefined;
let prevPro = this.tableData[index - 1].province
? this.tableData[index - 1].province
: undefined;
if (element.province == nextPro) {
provinceObj[element.province].push(index);
} else if (element.province == prevPro) {
provinceObj[element.province].push(index);
}
} else {
provinceObj[element.province] = [];
provinceObj[element.province].push(index);
}
});
// 将数组长度大于1的值 存储到this.OrderIndexArr(也就是需要合并的项)
for (let k in OrderObj) {
if (OrderObj[k].length > 1) {
this.OrderIndexArr.push(OrderObj[k]);
}
}
//修改的地方
for (let i in provinceObj) {
if (provinceObj[i].length > 1) {
this.handleData(provinceObj[i])
}
}
},
//新增的方法,处理当数组的长度大于2的时候
handleData(data){
let temp = data;
let itemArr = [];
let itemArrNew = [];
let resArr = [];
if (data.length>2) {
for (let i = 0; i < data.length; i++) {
if (data[i+1]) {
if (data[i+1] - data[i] > 1) {
itemArr = data.slice(0,i+1)
itemArrNew = temp.slice(i+1,temp.length)
break;
}else{
resArr = data
}
}
}
if (itemArr.length>0 || itemArrNew.length>0) {
this.provinceArr.push(itemArr)
this.provinceArr.push(itemArrNew)
}else{
this.provinceArr.push(data)
}
}else{
this.provinceArr.push(data)
}
},