需求说明
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' } // 后面其他的列,省略 ]
文章评论