15_通过指令实现table行合并
实现效果
组件前提
iview 3.x版本的 table 组件并没有实现表格合并的功能;模拟4.x版本通过表格配置实现
本文通过指令实现 dom 操作
字段说明
- ld:表格数据来源
- columns:表头
- showData:展示列表
- spanMsg:对象数组
[{ 0: 5, 5: 3 }, { 0: 2, 2: 3}]
每一个对象代表一列{0: 5, 5: 3}
表示从 第 0 行开始向下合并 5 行, 从第 5 行开始向下合并 3 行
组件实现
span-table-template.vue
<Table
ref="table"
border
:columns="ld.columns"
:data="ld.showData"
:key="new Date().getTime()"
v-dealSpan="spanMsg"
></Table>
props: {
ld: Object,
spanMsg: Array
}
directives: {
dealSpan: {
bind(el, binding, vnode) {
// 表格上下文
const __this = vnode.context;
// 指令传参
const spanMsg = binding.value;
__this.$nextTick(() => {
// 表格行
const rows = el.querySelectorAll('tr.ivu-table-row');
// 列从后往前处理
for(let index = spanMsg.length - 1; index >= 0; index--) {
let item = spanMsg[index]; // 处理某一列
let rowIndex = 0;
// 需使用 for..of 遍历节点
for(let rowItem of rows) {
let span = item[rowIndex]; // 某一列被合并的格数
if(span) {
// 给被合并到的单元格设置 rowspan 属性
rowItem.querySelector(`td:nth-of-type(${index + 1})`).setAttribute('rowspan', span);
// 记录 rowIndex < 列数 < span + rowIndex - 1 要移除第 index + 1 项
let dealNum = span + rowIndex - 1;
while(dealNum > rowIndex) {
rows[dealNum].querySelector(`td:nth-of-type(${index + 1})`).remove();
dealNum--;
}
}
rowIndex++;
}
}
});
}
}
}
应用
<SpanTableTemplate :ld="ld" :span-msg="[column1SpanMsg, column2SpanMsg]" />
async newSearch() {
const { data: result } = await this.$axios.get(this.apix.list);
this.ld.columns = this.setColumns(result.columns);
this.dealTableData(result.data);
}
dealTableData(table) {
const dataList = table.data_list;
const showData = [];
const column1SpanMsg = {};
const column2SpanMsg = {};
let lastTime = 0;
let lastIndex = 0;
let columnIndex = 0;
/**
* 思路:merge_time 下 json_cross.length
* column2SpanMsg: [{ item.index: json_cross.length }]
* column1SpanMsg: 若 item.merge_time 相同,则 [{ 0: add(json_cross.length) }]
*/
dataList.map(item => {
const { json_cross: cross, json_server: server, master_cross_id, merge_time: time } = item;
column2SpanMsg[columnIndex] = cross.length;
if (time === lastTime) {
column1SpanMsg[lastIndex] = column1SpanMsg[lastIndex] + cross.length;
} else {
lastIndex = columnIndex;
lastTime = time;
column1SpanMsg[lastIndex] = cross.length;
}
cross.map(crossItem => {
const { center_id, center_alias, wlevel, type } = crossItem;
const obj = {
merge_time: time,
master_center_id: master_cross_id,
slave_center_id: `${center_id}(${center_alias})`,
wlevel,
server_list: server[center_id]
.map(serverItem => `${serverItem.server_name}(${serverItem.server_alias})`)
.join(','),
type
};
columnIndex++;
showData.push(obj);
});
});
this.ld.showData = showData;
this.column1SpanMsg = column1SpanMsg;
this.column2SpanMsg = column2SpanMsg;
}
# 接口返回的数据结构
data_list: {
[{
id: 2,
json_cross: [
{ type: "master", center_id: 100007, center_alias: "cross_S100007", wlevel: 47 },
{ type: "slave", center_id: 100008, center_alias: "cross_S100008", wlevel: 45 }
],
json_server: {
100007: [
{ create_time: "2022-04-27 00:00:00", open_days: 582, server_alias: "test_S1001", server_id: 41, server_name: "更新服S1001" },
100008: [
{ create_time: "2022-04-27 00:00:00", open_days: 582, server_alias: "test_S1002", server_id: 42, server_name: "更新服S1002" },
{ create_time: "2022-04-27 00:00:00", open_days: 582, server_alias: "test_S1003", server_id: 43, server_name: "更新服S1003" }
]
},
master_cross_id: 100007,
merge_time: "2023-12-08 11:28:44",
oper_admin: "刘清发",
oper_time: "2023-11-29 11:29:02",
platform: "test",
remark: "",
slave_cross_id: "100008"
},
{
id: 1,
json_cross: [
{ type: "master", center_id: 100004, center_alias: "cross_S100007", wlevel: 47 },
{ type: "slave", center_id: 100005, center_alias: "cross_S100008", wlevel: 45 }
{ type: "slave", center_id: 100006, center_alias: "cross_S100008", wlevel: 45 }
],
json_server: {
100004: [
{ create_time: "2022-04-27 00:00:00", open_days: 582, server_alias: "test_S1001", server_id: 41, server_name: "更新服S1001" },
100005: [
{ create_time: "2022-04-27 00:00:00", open_days: 582, server_alias: "test_S1002", server_id: 42, server_name: "更新服S1002" },
{ create_time: "2022-04-27 00:00:00", open_days: 582, server_alias: "test_S1003", server_id: 43, server_name: "更新服S1003" }
],
100006: [
{ create_time: "2022-04-27 00:00:00", open_days: 582, server_alias: "test_S1004", server_id: 44, server_name: "更新服S1004" },
{ create_time: "2022-04-27 00:00:00", open_days: 582, server_alias: "test_S1005", server_id: 45, server_name: "更新服S1005" }
]
},
master_cross_id: 100004,
merge_time: "2023-12-08 11:28:44",
oper_admin: "刘清发",
oper_time: "2023-11-29 11:29:02",
platform: "test",
remark: "",
slave_cross_id: "100005, 100006"
}]
}