一、场景
1.table 根据tableHead 批量自定义 sortMethod排序
这里可以看见当前table 是根据 tableHead 批量遍历渲染出来了,如果我们采取每行 el-table-column 直接写出方式也是可以实现,但是这很蠢,每个都要单独写个方法去进行排序,这对于想要既优雅又偷懒少写几行代码的码农来说是不可能的!
2.查阅 element ui-table 文档 sort-method 自定义相关排序
二、改进
1.改进版一
<template>
<el-table
:key="key" align="center"
:width="item.width" v-for="(item, key) in tableHead" :label="item.title">
<el-table-column type="selection" width="40"></el-table-column>
<el-table-column type="index" label="序号"></el-table-column>
<el-table-column prop="brandName" label="客户名称" width="100"></el-table-column>
<el-table-column prop="totalCommCnt" label="货物数量" width="100" :sortable="true" :sort-method="(a,b) => sortMethodFunc(a ,b , 'totalCommCnt')"></el-table-column>
<el-table-column prop="createTime" label="到期时间" width="100" :sortable="true" :sort-method="(a,b) => sortMethodFunc(a ,b , 'createTime')"></el-table-column>
<el-table-column prop="totalVolume" label="体积(m³)" width="100" :sortable="true" :sort-method="(a,b) => sortMethodFunc(a ,b , 'totalVolume')"></el-table-column>
<!--<el-table-column label="操作" width="100" fixed="right">-->
<!--<template slot-scope="scope">-->
<!--<el-button type="text" size="mini" @click="handleUpdate(scope.row)">编辑</el-button>-->
<!--</template>-->
<!--</el-table-column>-->
</el-table>
</template>
// table 排序
sortMethodFunc(obj1, obj2, column) {
// console.log('sortMethodFunc()-obj1', obj1, 'obj2', obj2, 'column', column)
if (column === 'createTime') {
let val1 = new Date(obj1.createTime).getTime()
let val2 = new Date(obj2.createTime).getTime()
if (val1 > val2) {
return -1
} else {
return 1
}
} else if (column === 'totalCommCnt') {
let val1 = obj1.totalCommCnt
let val2 = obj2.totalCommCnt
if (val1 > val2) {
return -1
} else {
return 1
}
}
},
这种也算解决问题了,但是还是不够优化,因为table每行数据是根据 tableHead 批量自定义渲染出来的。
2.改进版二
效果图
重点讲解
:sort-method="(a,b) => sortMethodFunc(a ,b , item.key)" 通过箭头函数 接收(a,b)参数 然后传入 sortMethodFunc自定义方法 然后同时带上对应字段 item.key
<el-table-column :key="index" align="center"
:sortable="item.sortable"
:sort-orders="['ascending', 'descending', null]"
:default-sort="{prop: 'totalVolume', order: 'ascending'}"
:sort-method="(a,b) => sortMethodFunc(a ,b , item.key)"
:width="item.width" v-for="(item, index) in tableHead" :label="item.title">
<template slot-scope="scope">
<!--<div v-if="value.key === 'gmtCreate'">{{scope.row.gmtCreate | parseTime('{y}-{m}-{d} {h}:{i}:{s}')}}</div>-->
<div>{{scope.row[value.key]}}</div>
</template>
</el-table-column>
:sortable="item.sortable" 控制这个字段是否开启升序排序
:sort-orders="['ascending', 'descending', null]" 见 element-ui文档 table 查询 sort-orders
:default-sort="{prop: 'totalVolume', order: 'ascending'}" default-sort 是设置默认采取(某个字段)排序方式,这里 totalVolume 是字段名称(体积m3)
控制排序方法
这里可以 根据 column 看是那个字段 比如是 时间单位 或者是数字单位 的字段,对应进行处理排序逻辑
// table 排序
sortMethodFunc(obj1, obj2, column) {
// console.log('sortMethodFunc()-obj1', obj1, 'obj2', obj2, 'column', column)
let val1 = obj1[column]
let val2 = obj2[column]
if (val1 && val2) {
if (val1 > val2) {
return -1
} else {
return 1
}
} else {
return 0
}
},
完整代码
<template>
<div class="web-main">
<!--功能-->
<!--<el-row class="web-header">-->
<!--<el-col :span="16">-->
<!--<el-button type="primary" @click="createBtn">新增</el-button>-->
<!--</el-col>-->
<!--</el-row>-->
<!--查询条件-->
<!--<el-form class="web_form" :inline="true" label-width="140px" style="margin: 6px 0 0 0">-->
<!--<el-form-item label="是否油价联动">-->
<!--<el-select v-model="page.condition.linkFlag" class="w184" clearable filterable remote reserve-keyword placeholder="请选择状态">-->
<!--<el-option key="1" label="否" value="0"></el-option>-->
<!--<el-option key="2" label="是" value="1"></el-option>-->
<!--</el-select>-->
<!--</el-form-item>-->
<!--<el-form-item class="search-box">-->
<!--<el-button type="primary" @click="search">查询</el-button>-->
<!--<el-button type="primary" @click="resetSearch">重置</el-button>-->
<!--</el-form-item>-->
<!--</el-form>-->
<!--主列表-->
<div style="width: 100%;position: relative;">
<el-table
:data="tableData" ref="mainTable"
stripe fit highlight-current-row
v-loading="listLoading" height="650"
element-loading-text="正在加载中..."
header-row-class-name="table-header-center"
@select="handleSelectionChange"
style="margin: 0 4px;">
<el-table-column type="selection" width="40"></el-table-column>
<el-table-column type="index" label="序号"></el-table-column>
<el-table-column :key="index" align="center"
:sortable="item.sortable"
:sort-orders="['ascending', 'descending', null]"
:default-sort="{prop: 'totalVolume', order: 'ascending'}"
:sort-method="(a,b) => sortMethodFunc(a ,b , item.key)"
:width="item.width" v-for="(item, index) in tableHead" :label="item.title">
<template slot-scope="scope">
<!--<div v-if="value.key === 'gmtCreate'">{{scope.row.gmtCreate | parseTime('{y}-{m}-{d} {h}:{i}:{s}')}}</div>-->
<div>{{scope.row[value.key]}}</div>
</template>
</el-table-column>
<!--<el-table-column label="操作" width="100" fixed="right">-->
<!--<template slot-scope="scope">-->
<!--<el-button type="text" size="mini" @click="handleUpdate(scope.row)">编辑</el-button>-->
<!--</template>-->
<!--</el-table-column>-->
</el-table>
</div>
<!-- 分页 -->
<el-pagination
style="margin-top: 8px"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="page.current"
:page-sizes="[10, 20, 30, 40]"
:page-size="page.size"
layout="total, sizes, prev, pager, next, jumper"
:total="page.total">
</el-pagination>
</div>
</template>
<script>
// import * as SendByDriverLspMgt from '@/api/sendByDriverLspMgt'
// import * as Utils from '@/utils/index'
const defaultTableData = [
{ key: 'brandName', title: '客户名称', width: '120', sortable: false },
{ key: 'totalCommCnt', title: '货物数量', width: '100', sortable: true },
{ key: 'totalWeight', title: '重量(吨)', width: '100', sortable: true },
{ key: 'totalVolume', title: '体积(m³)', width: '100', sortable: true },
];
export default {
name: '',
components: { },
data() {
return {
tableHead: defaultTableHead,
searchFlag: true,
listLoading: false,
tableData: [],
selectRow: [],
page: { current: 1, size: 10, total: 1,
condition: {
}
}
}
},
created() {
this.getList()
},
methods: {
// table 排序
sortMethodFunc(obj1, obj2, column) {
// console.log('sortMethodFunc()-obj1', obj1, 'obj2', obj2, 'column', column)
let val1 = obj1[column]
let val2 = obj2[column]
if (val1 && val2) {
if (val1 > val2) {
return -1
} else {
return 1
}
} else {
return 0
}
},
// 列表查询
getList() {
const that = this
// SendByDriverLspMgt.querySdBaseDataInfoPage(that.page).then(res => {
// const t = res.data
// that.tableData = t.records
// that.page.current = t.current
// that.page.size = t.size
// that.page.total = t.total
// }).catch(err => {
// console.log('error', err)
// })
that.tableData = [
{ brandName: '客户1', totalCommCnt: '1', totalWeight: '2.222', totalVolume: '3' },
{ brandName: '客户2', totalCommCnt: '2', totalWeight: '0.85', totalVolume: '9' },
{ brandName: '客户3', totalCommCnt: '3', totalWeight: '4', totalVolume: '6' },
]
that.page.current = 1
that.page.size = 3
that.page.total = 3
},
// 更多
moreSearch() {
this.searchFlag = !this.searchFlag
},
// 查询
search() {
this.page.current = 1
this.page.size = 10
this.getList()
},
handleSizeChange(val) {
this.page.size = val
this.page.current = 1
this.getList()
},
handleCurrentChange(val) {
this.page.current = val
this.getList()
},
// 重置
resetSearch() {
this.page.current = 1
this.page.size = 10
this.page.condition = {
}
this.getList()
},
// 检查是否选择单条
checkSelect(data) {
const l = data.length
if (l === 0) {
this.$message({
message: '未选择',
type: 'warning',
duration: 2000
})
return false
}
return true
},
// 表格改变时
handleSelectionChange(val) {
this.selectRow = val
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
</style>