一、问题描述
默认el-table是单个字段排序的,点击表格头排序,老排序字段的排序箭头样式并没有保留,仅仅保留了新点击字段的样式。
二、实现效果
选择多列组合排序时可以高亮多列箭头。
三、解决方法
3.1 如何记录多个字段被选择?
表格绑定@sort-change="handleSortChange",通过打印发现存在ascending升序、descending降序、null空三种状态。
{
"serial_id": "ascending",
"product_id": "descending",
"product_name": null
}
故可以定义一个Map对象变量,来存储排序字段和排序方式。在点击新排序字段时,如果order不为null,则插入Map中,如果为null,则移除map。再将sortField中的排序字段和排序方式拼接成一个字符串,发送到后端完成排序,关键代码如下:
const sortField = new Map<string, any>();
function updateOrderBy() {
let orderByList: string[] = [];
for (const [key, value] of sortField) {
if (value) {
orderByList.push(key + "_" + value)
}
}
if (orderByList.length > 0) {
queryParams.orderBy = orderByList.join(",")
} else {
queryParams.orderBy = undefined;
}
console.log("sortField", sortField);
console.log("orderBy", queryParams.orderBy);
}
const handleSortChange = (params: any) => {
const hasprop = sortField.has(params.prop);
if (hasprop == true && params.order == null) {
sortField.delete(params.prop); //取消排序字段
} else {
sortField.set(params.prop, params.order);
}
updateOrderBy();
handleQuery();
}
3.2 如何保留历史点击字段的样式?
有个特性可以利用,当点击排序时,header-cell-class-name属性绑定的事件会被触发,而在其回调中我们又可以拿到column 属性,有了这个属性,我们就可以设置column的 order 属性,从而显式的控制样式了。
:header-cell-class-name="(params:any) => {setHeaderClass(params)}"
function setHeaderClass(params:any) {
if ( sortField.has(params.column.property)) {
params.column.order = sortField.get(params.column.property)
}
}
<el-table
ref="dataTableRef"
v-loading="loading"
:data="pageList"
:header-cell-class-name="(params:any) => {setHeaderClass(params)}"
@sort-change="handleSortChange"
>
3.3 为什么采用Map,而不采用字典存储?
为了保证排序的先后顺序,存储结构必须为有序的。在TypeScript中,采用字典{}类型会出现无序的情况,无法保证按照插入顺序输出。而Map是一种有序的键值对集合,可以按照插入顺序输出。以下是一个示例代码,展示了如何使用Map来按照插入顺序输出字典的属性:
const dictionary = new Map<string, any>();
dictionary.set("name", "John");
dictionary.set("age", 30);
dictionary.set("address", "123 Main St");
for (const [key, value] of dictionary) {
console.log(key, value);
}
在这个示例中,我们创建了一个Map对象dictionary,并使用set方法按照插入顺序添加了键值对。
然后,我们使用for...of循环遍历dictionary,并使用解构赋值将键和值分别赋给key和value变量。这样就可以按照插入顺序输出字典的属性。