需求说明
iView的表格虽然有了很多定制化的功能,不过有一个需求,官方始终没有实现,那就是表格的分组功能,来看下这个需求,客户想要实现如图的分组功能:
根据时间的不同,按照『今天』,『昨天』,『一周内』,『一个月内』,『更早』,另外根据其他需求的不同,根据其他类别进行分组展示。
硬核独家实现
虽然官方没有提供现成的解决方案,不过iView表格文档的『特定样式』进行改造,来实现这部分效果。这部分网上查了没有相关的实现,是我自己想出来的,应该算是独家吧,哈哈。
如上图,分组显示的列其实也是普通的一行,只是使用列合并把整行都跨过去了。另外针对这种特殊的行(带有_group的)加上了特定的样式。
HTML代码如下:
<i-table stripe border :columns="columns" :data="list" :row-class-name="rowClassName" :span-method="handleSpan"></i-table>
rowClassName就是定制分组表头的样式,handleSpan就进行列合并:
handleSpan({row, column, rowIndex, columnIndex}) {
if (row['_group']) {
return columnIndex === 0 ? [1, this.columns.length] : [1, 0];
}
return [1, 1]
},
rowClassName(row, index) {
if (row['_group']) {
return 'group-row';
}
return '';
},
分组行用到的样式:
<style type="text/css">
/*自定义表格分组*/
.ivu-table .group-row td {
background-color: #D7D9DD !important;
height: 32px;
font-weight: 600;
text-align: left;
/*color: #fff;*/
}
.ivu-table .group-row1 td {
background-color: #D7D9DD !important;
height: 32px;
padding-left: 60px;
font-weight: 600;
text-align: left;
/*color: #fff;*/
}
.span-min-with-item {
display: inline-block;
min-width: 80px;
font-weight: 600;
}
</style>
list就是数组数据,我们对后端返回的数据进行了分组再处理,给新的一行加上特殊的标记(_group)标志这这一行是分组行
function groupList(list, keyGetter, type, noGetter) {
if(!list) {
return [];
}
const map = new Map();
let emptyKey = false;
list.forEach((item) => {
let key = keyGetter(item);
if (key && type === 'date') {
let date = moment(key);
if (date.isValid()) {
if (date.isSame(moment(), "day")) {
key = "今天";
} else if (date.isSame(moment().subtract(1, 'days'), "day")) {
key = '昨天';
} else if (date.isSame(moment().subtract(2, 'days'), "day")) {
key = '前天';
} else if (date.isAfter(moment().subtract(7, 'days'), "day")) {
key = '一周内';
} else if (date.isAfter(moment().subtract(1, 'months'), "day")) {
key = '一月内';
} else {
key = date.format("更早");
// key = date.format("YYYY-MM");
// key = date.format("YYYY-MM-DD");
}
}
}
if (!key) {
key = '--';
emptyKey = true;
}
const collection = map.get(key);
if (!collection) {
map.set(key, [item]);
} else {
collection.push(item);
}
});
if (map.size === 1 && emptyKey) {//只有一个,而且是空的,就不分组了
return list;
}
let newItems = [];
map.forEach((value, key) => {
if (key) {
let itm = {_group: key};
if (noGetter) {
itm['_groupNo'] = noGetter(value[0]);
}
newItems.push(itm);
}
newItems.push(...value);
});
// console.log(newItems)
return newItems;
}
以上是分组加工使用的工具方法,我们对后台传过来的list进行如下处理:
var list = [];//后台传来的数据,这里省略 // 对数据的startDate进行分组,分组后,会对不同的组。加上一行特殊的行,(带有_group) this.list = groupList(list, itm => itm["startDate"], "date");
columns的定义如下:
var columns = [
{
title: '审批状态',
width: 110,
key: 'action',
render: function (h, params) {
// 第一列是带有分组标志的,特殊返回
if(params.row['_group']) {
return h("span", params.row['_group']);
}
var found = app.actions.find(function (item) {
return item.id == params.row.action;
});
var foundName = found ? found.name : '';
var color = 'default';
switch (params.row.action) {
case 1:
color = 'success';
break;
case 0:
color = 'warning';
break;
case 3:
color = 'volcano';
break;
case 2:
case 4:
color = 'error';
break;
default:
break;
}
return h('Tag', {
props: {color: color}
}, foundName)
},
filters: this.actions.map(function (item) {
return {label: item.name, value: item.id}
}),
filterMultiple: false,
filterRemote: function (value) {
app.filterColumn = 'action';
app.filterValue = value.length > 0 ? value[0] : '';
app.loadList(1);
}
},
{
title: '仪器名称',
minWidth: 180,
key: 'equipName',
sortable: 'custom'
}
// 后面其他的列,省略
]

文章评论