实现的功能点
1. 支持多个字段
同时
排序
2. 多个排序字段高亮箭头
正常显示
3. 多列排序添加默认排序规则
实现的效果图
用到的属性和方法
el-table属性
1. header-cell-style 表头单元格的 style 的回调方法,也可以使用一个固定的 Object 为所有表头单元格设置一样的 Style(解决多列排序字段箭头高亮问题)
el-table-column属性
1. sortable 是否可以排序(true, false, ‘custom’),为’custom’时,代表用户希望远程排序,需要加 sort-change 事件(我这块介绍的就是值为custom的)
方法
1. @sort-change点击排序小箭头触发的事件
功能点的完整代码
<template>
<div>
<div style="float: left; margin-bottom: 20px">
<slot name="btnList" />
</div>
<el-table
ref="table"
v-loading="loading"
element-loading-text="数据加载中"
:data="tableData"
:row-key="id"
highlight-current-row
show-overflow-tooltip
:pager-count="pagerCount"
:row-class-name="rowClassName"
:cell-style="{ padding: 0 }"
:row-style="{ height: '39px' }"
style="width: 100%"
:height="tableH"
:header-cell-style="handleTheadStyle"
@selection-change="handleSelectionChange"
@select="select"
@sort-change="sortChange"
>
<el-table-column
v-if="checkSelection"
:reserve-selection="reserveSelection"
type="selection"
width="50"
:selectable="checkSelectSet"
fixed
/>
<el-table-column
v-if="order"
label="序号"
type="index"
width="50"
align="center"
fixed
/>
<el-table-column
v-for="(item, index) in columns"
:key="index"
:align="item.align ? item.align : 'left'"
:prop="item.key"
:label="item.label"
:min-width="item.minWidth"
:fixed="item.fixed"
:sortable="item.sortable ? item.sortable : false"
show-overflow-tooltip
>
<template v-if="item.slot" #default="{ row, rowIndex }">
<slot
:name="item.slot"
:row="row"
:column="item"
:index="rowIndex"
class="btn"
/>
</template>
<template v-else #default="{ row }">
<span>{{ row[item.key] || "-" }}</span>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0 && !hidePagenation"
:total="total"
:page.sync="queryParams.pageNum"
:page-sizes="[15, 25, 50, 100]"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
</template>
<script>
export default {
props: {
// ...省略其它属性
// 默认排序规则
multiSortConditions: {
type: Array,
},
},
data() {
return {
sortCols: [], // 所有排序字段
activeThead: {}, // 记录每个排序字段的排序规则
};
},
mounted() {
// 进入页面后使排序规则生效
this.applyDefaultSort();
},
methods: {
applyDefaultSort() {
if (!this.multiSortConditions?.length) return;
// 根据排序规则手动触发 sortChange 方法
this.multiSortConditions.forEach((condition) => {
this.sortChange({
column: { property: condition.prop },
prop: condition.prop,
order: condition.order,
});
});
},
/**
* 触发的排序方法
* 接收一个对象参数,包含三个属性:
* column:列对象
* prop:属性名(指定排序的字段)
* 排序顺序: ascending 升序,descending 降序,null 表示还原为原始顺序
*/
sortChange({ column, prop, order }) {
// 过滤掉不参与排序的字段
this.sortCols = this.sortCols.filter((item) => item.prop !== prop);
// 判断sortCols数组中是否已经存在排序字段
if (this.sortCols.some((item) => item.prop === prop)) {
const index = this.sortCols.findIndex((item) => item.prop === prop);
// 如果排序规则为null则从sortCols数组中移除该项,否则更新该项的排序顺序
if (order === null) {
this.sortCols.splice(index, 1);
} else {
this.sortCols[index].order = order;
}
} else {
this.sortCols.push({ prop, order });
}
// 下面代码为更新表头排序状态
if (!this.sortCols) return;
// 如果order排序顺序存在,则更新表头排序状态,否则清除当前表头的排序状态
if (order) {
this.activeThead[prop] = order;
} else if (!order) {
this.activeThead[prop] = "";
}
this.$emit("sortChange", this.sortCols);
},
// 处理表格表头的样式
handleTheadStyle({ column }) {
if (!this.sortCols) return;
// activeThead对象中若存在与当前列属性对应的排序状态
if (this.activeThead[column.property]) {
// 设置当前列排序样式(小箭头图标)
column.order = this.activeThead[column.property];
}
},
// ... 省略其它方法...
},
};
</script>
<style lang="scss" scoped>
.el-button {
height: 34px;
}
::v-deep .el-table__header {
background-color: red !important;
}
</style>