前言

element-ui 在 el-table 组件中提供了很多可用于排序的属性和方法,可用于前端排序或者后端排序。相对于前端排序,后端排序更复杂一些,也更常用一些。下面记录的是在实现后端排序时,实现多列排序的过程。

实现多列排序

  • 为单列添加排序

    根据 element-ui 的文档,可以很容易的实现一个后端排序。

    使用 el-table 实现后端排序,需将 sortable 设置为 custom,同时在 table 上监听sort-change 事件,在事件回调中可以获取当前排序的字段名和排序顺序,从而向接口请求排序后的表格数据。下面是简单的代码片段示例:

//  templete 部分 table 代码片段
<el-table
  :data="tableData"
  @sort-change="handleSortChange"
>
  <el-table-column
    prop="lineNo1"
    label="行号1"
    sortable="custom"
  />
</el-table>

// script 部分
// 数据
orderItem: {}

// 方法
// 自定义排序
handleSortChange({ column, prop, order }) {
  // 根据项目中 API 的实际参数要求,构建对应的排序参数
  this.orderItem = {
    asc: order === "ascending" ? true : false,
    column: prop
  };
  // 使用构建好的排序参数,请求后端排序好的列表数据 tableData
  this.getTableData(this.orderItem);
}

上面的代码,将表格中的行号 1 列( lineNo1 )添加了自定义排序功能。同时,通过在 sort-change 事件的回调函数中,向后端请求对应的排序后的数据。这 2 步就已经完成了一个简单的后端排序列。

  • 为多列添加排序
    It seems so easy? 在表格中,需要排序的另外一列,比如行号2 添加上 sortable="custom"不就搞定了!
<el-table
  :data="tableData"
  @sort-change="handleSortChange"
>
  <el-table-column
    prop="lineNo1"
    label="行号1"
    sortable="custom"
  />
  <el-table-column
    prop="lineNo2"
    label="行号2"
    sortable="custom"
  />
</el-table>

需要注意的是,目前的 handleSortChange 事件处理函数只能实现单列排序,要想实现多列数据共同排序,还需要改造 排序参数结构 以及 事件处理函数

// script 部分
// 数据
orderItems: []

// 方法
handleSortChange({ column, prop, order }) {
  let asc = order === "ascending" ? true : false;
  for (let i = 0; i < this.orderItems.length; i++) {
    const element = this.orderItems[i];
    if (element.column === prop) {
      element.asc = asc;
      this.getTableData(this.orderItems);
      return;
    }
  }
  let item = {
    asc: asc,
    column: prop
  };
  this.orderItems.push(item);
  this.getTableData(this.orderItems);
}

这一步,也是很容易想到的!接下来,就 amazing 了。

  • 每次只有一列显示排序样式?
    点了 行号1 排序,再点 行号2 排序,看请求参数,第二次点击触发的请求参数中的确是包括了 行号1 和 行号2 的排序数据了,可是只有 行号2 的有排序样式(这样不是会给用户带来很大的困扰吗),怎么回事?

这是因为 element-ui 默认是只支持单行排序的,所以每次都只有最后一次点击的排序列图标会有颜色样式。怎么让数据和表现保持一致(在这,就是保持排序数据与排序图标样式的一致)呢?

打开控制台,观察了一番,发现排序图标的样式,是通过在排序图标上动态添加 .active-thead-desc.active-thead-desc.active-thead-null 这几个样式类实现的。那只要按我们需要的表现,给表头添加样式不就能解决上面的问题了嘛!代码如下:

// 从控制台里找到的样式
// 排序图标样式
.active-thead-desc > .cell > .caret-wrapper > .sort-caret.descending {
  border-top-color: #409eff !important;
}
.active-thead-asc > .cell > .caret-wrapper > .sort-caret.ascending {
  border-bottom-color: #409eff !important;
}
.active-thead-null > .cell > .caret-wrapper > .sort-caret.descending {
  border-top-color: #c0c4cc !important;
}
.active-thead-null > .cell > .caret-wrapper > .sort-caret.ascending {
  border-bottom-color: #c0c4cc !important;
}
handleTheadAddClass({ row, column, rowIndex, columnIndex }) {
   for (let i = 0; i < this.orderItems.length; i++) {
     const element = this.orderItems[i];
     if (column.property === element.column) {
       if (element.asc) {
         return "active-thead-asc";
       } else {
         return "active-thead-desc";
       }
     }
   }
   if (this.orderItems.length === 0) {
     return "active-thead-null";
   }
 }

最最关键的一点,记得在 el-table 上使用 header-cell-class-name 属性为表头单元格绑定样式。
header-cell-class-name 属性描述

:header-cell-class-name="handleTheadAddClass"
Logo

前往低代码交流专区

更多推荐