vue+elementui 项目 table表格自定义排序规则

本文介绍了在Vue+ElementUI项目中如何实现表格的自定义排序规则,特别是在列包含下拉列表等特殊内容时,通过设置`sortable`属性为`custom`并结合`sort-change`事件来处理排序混乱的问题。示例代码展示了如何定义`sortFun`方法进行自定义比较,以及在`sort-change`事件中调用该方法更新表格数据。

vue+elementui 项目 table表格自定义排序规则

官方解释:
在列中设置 sortable 属性即可实现以该列为基准的排序,接受一个 Boolean,默认为 false。可以通过 Table 的 default-sort 属性设置默认的排序列和排序顺序。可以使用 sort-method 或者 sort-by 使用自定义的排序规则。如果需要后端排序,需将 sortable 设置为 custom,同时在 Table 上监听 sort-change 事件,在事件回调中可以获取当前排序的字段名和排序顺序,从而向接口请求排序后的表格数据。

其实前端排序要使用自定义排序规则也可以将 table 的 el-table-column 标签上 sortable 属性设置为 custom,要不然在排序一些特殊内容的时候就会出现乱象,比如:排序的列都是下拉列表的时候,就会出现乱象问题

<el-table-column
   :label="tableItemConfig.label"
   :min-width="tableItemConfig.width"
   align="center"
   :prop="tableItemConfig.prop"
   sortable="custom"
>

在 el-table 标签上绑定 sort-change 事件

<el-table
   ref="table"
   :data="tablePageData"
   :show-header="tableConfig.isShowHeader ? tableConfig.isShowHeader : true"
   :border="tableConfig.isShowBorder"
   :style="tableConfig.tableStyle"
   :header-cell-style="tableConfig.headerCellStyle"
   :row-style="tableRowStyle"
   @sort-change="sort_change"
>
methods: {
  sort_change(column) {
	this.tablePageData= this.tablePageData.sort(sortFun(column.prop, this.searchDataOrder))
  },

  // attr 参数表示当前点击的是哪一列,传进来的是点击列的标识
  // rev 参数表示的是点击当前列表头之后是升序降序或者null,三种值分别是['ascending', 'descending', null]
  sortFun = (attr, rev) => {
    if(rev === 'ascending') {
      rev = 1
    } else if (rev === 'descending') {
      rev = -1
    } else {
      rev = 0
    }
    return function (x, y) {
      let a = x[attr]
      let b = y[attr]
      if (!a) {
        a = ""
      }
      if (!b) {
        b = ""
      }
      if (a < b) {
        return rev * -1
      }
      if (a > b) {
        return rev * 1
      }
      return 0
    }
  }
}
要实现 Vue + Element UI 根据后端返回的动态字段数据构建表格展示,关键在于: - 前端动态生成 `el-table-column`; - 使用 `Map` 结构的数据渲染每一行; - 支持字段的增删改查扩展。 --- ### ✅ 实现步骤 #### 1. 接口响应格式(回顾) 后端返回结构如下: ```json { "list": [ { "id": 1, "archiveNumber": "AR20250401001", "title": "发票001", "archiveType": "invoice", "businessDate": "2025-04-01", "invoice_number": "IN20250401001", "invoice_code": "IC20250401001", "amount": "1000.00", "tax_amount": "100.00" } ], "pageNum": 1, "pageSize": 10, "total": 100 } ``` --- #### 2. 前端组件结构(Vue + Element UI) ```vue <template> <el-table :data="tableData" border style="width: 100%"> <el-table-column prop="id" label="ID" width="80"></el-table-column> <el-table-column prop="archiveNumber" label="档案编号" width="150"></el-table-column> <el-table-column prop="title" label="标题" width="150"></el-table-column> <el-table-column prop="archiveType" label="档案类型" width="120"></el-table-column> <el-table-column prop="businessDate" label="业务日期" width="150"></el-table-column> <!-- 动态列 --> <el-table-column v-for="col in dynamicColumns" :key="col.key" :prop="col.key" :label="col.label" min-width="120" > </el-table-column> </el-table> <!-- 分页 --> <el-pagination layout="prev, pager, next" :total="total" :page-size="pageSize" @current-change="handleCurrentChange" /> </template> <script> export default { data() { return { tableData: [], dynamicColumns: [], // 动态列定义 total: 0, pageNum: 1, pageSize: 10 }; }, created() { this.fetchData(); }, methods: { async fetchData() { const res = await this.$axios.get('/archives/list', { params: { archiveType: 'invoice', pageNum: this.pageNum, pageSize: this.pageSize } }); // 提取动态列 const firstRow = res.data.list[0] || {}; this.dynamicColumns = Object.keys(firstRow) .filter(key => !['id', 'archiveNumber', 'title', 'archiveType', 'businessDate'].includes(key)) .map(key => ({ key, label: this.humanizeKey(key) })); this.tableData = res.data.list; this.total = res.data.total; }, humanizeKey(key) { // 可替换为从后端返回的 description 字段 return key .split('_') .map(word => word.charAt(0).toUpperCase() + word.slice(1)) .join(' '); }, handleCurrentChange(page) { this.pageNum = page; this.fetchData(); } } }; </script> ``` --- ### ✅ 优化建议 - **字段中文标签**:建议后端在返回字段定义时,也返回 `description`,前端使用该字段作为列标题。 - **字段排序**:可以按 `sort_order` 排序字段,控制前端列顺序。 - **字段隐藏**:通过配置字段是否可见,控制是否渲染某些列。 - **字段类型渲染**:如金额、日期等字段可以使用 `formatter` 自定义渲染。 --- ### ✅ 示例:带 description 的字段定义返回 ```json { "columns": [ { "key": "invoice_number", "label": "发票号码" }, { "key": "invoice_code", "label": "发票代码" }, { "key": "amount", "label": "金额" }, { "key": "tax_amount", "label": "税额" } ], "data": [ ... ] } ``` 前端直接使用 `column.label` 显示列标题。 --- ### ✅ 总结 通过 Vue 动态渲染 `el-table-column`,结合后端返回的 `key-value` 数据结构,你可以灵活地实现 **动态表格展示**,适用于发票、合同、销售单等多种档案类型。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值