el-table支持多列同时排序

实现的功能点

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>
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值