feat(报表组件): 为线圈表格添加筛选、排序和分页功能
添加关键词筛选、多列选择筛选、字段排序和分页控制功能 优化表格布局和响应式设计 重构数据处理逻辑实现前端筛选和排序
This commit is contained in:
@@ -1,8 +1,34 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="coil-table">
|
<div class="coil-table">
|
||||||
<!-- 其他props -->
|
<div class="table-controls">
|
||||||
|
<div class="filter-section">
|
||||||
|
<el-input v-model="filterKeyword" placeholder="输入关键词筛选" clearable @input="handleFilterChange"
|
||||||
|
style="width: 200px; margin-right: 10px" />
|
||||||
|
<el-select v-model="filterColumn" placeholder="选择筛选字段" @change="handleFilterChange"
|
||||||
|
style="width: 200px; margin-right: 10px"
|
||||||
|
multiple
|
||||||
|
collapse-tags>
|
||||||
|
<el-option v-for="column in columns" :key="column.prop" :label="column.title" :value="column.prop" />
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
<div class="sort-section">
|
||||||
|
<el-select v-model="sortField" placeholder="选择排序字段" @change="handleSortChange"
|
||||||
|
style="width: 150px; margin-right: 10px">
|
||||||
|
<el-option v-for="column in columns" :key="column.prop" :label="column.title" :value="column.prop" />
|
||||||
|
</el-select>
|
||||||
|
<el-select v-model="sortDirection" placeholder="选择排序方向" @change="handleSortChange" style="width: 100px">
|
||||||
|
<el-option label="升序" value="asc" />
|
||||||
|
<el-option label="降序" value="desc" />
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
<el-pagination layout="total, sizes, prev, pager, next, jumper" :total="total" :page-size.sync="pageSize"
|
||||||
|
:page-sizes="[10, 20, 50, 100, 200, 500, 1000]" @size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange" />
|
||||||
|
</div>
|
||||||
|
|
||||||
<el-table :data="tableData" style="width: 100%" height="calc(100vh - 320px)" border>
|
<el-table :data="tableData" style="width: 100%" height="calc(100vh - 320px)" border>
|
||||||
<el-table-column v-for="column in columns" :key="column.prop" :prop="column.prop" :label="column.title" :width="column.width" :align="column.align">
|
<el-table-column v-for="column in columns" :key="column.prop" :prop="column.prop" :label="column.title"
|
||||||
|
:width="column.width" :align="column.align">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<!-- 特殊 prop 渲染逻辑 -->
|
<!-- 特殊 prop 渲染逻辑 -->
|
||||||
<template v-if="column.prop === 'enterCoilNo'">
|
<template v-if="column.prop === 'enterCoilNo'">
|
||||||
@@ -29,15 +55,6 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
<el-pagination
|
|
||||||
v-if="showPagination"
|
|
||||||
layout="total, sizes, prev, pager, next, jumper"
|
|
||||||
:total="total"
|
|
||||||
:page-size.sync="pageSize"
|
|
||||||
:page-sizes="[10, 20, 50, 100, 200, 500, 1000]"
|
|
||||||
@size-change="handleSizeChange"
|
|
||||||
@current-change="handleCurrentChange"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -67,20 +84,80 @@ export default {
|
|||||||
return {
|
return {
|
||||||
pageNum: 1,
|
pageNum: 1,
|
||||||
pageSize: 1000,
|
pageSize: 1000,
|
||||||
|
// 排序相关
|
||||||
|
sortField: '',
|
||||||
|
sortDirection: 'asc',
|
||||||
|
// 筛选相关
|
||||||
|
filterKeyword: '',
|
||||||
|
filterColumn: [],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
mounted() {
|
||||||
|
// 默认选中所有列
|
||||||
|
this.filterColumn = this.columns.map(column => column.prop)
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
// 处理排序和筛选后的数据
|
||||||
|
processedData() {
|
||||||
|
let result = [...this.data]
|
||||||
|
|
||||||
|
// 筛选逻辑
|
||||||
|
if (this.filterColumn.length > 0 && this.filterKeyword) {
|
||||||
|
const keyword = this.filterKeyword.toLowerCase()
|
||||||
|
result = result.filter(item => {
|
||||||
|
// 只要有一个字段匹配,就保留该记录
|
||||||
|
return this.filterColumn.some(column => {
|
||||||
|
const value = item[column]
|
||||||
|
if (value === null || value === undefined) return false
|
||||||
|
return String(value).toLowerCase().includes(keyword)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 排序逻辑
|
||||||
|
if (this.sortField) {
|
||||||
|
result.sort((a, b) => {
|
||||||
|
const aValue = a[this.sortField]
|
||||||
|
const bValue = b[this.sortField]
|
||||||
|
|
||||||
|
// 处理null和undefined
|
||||||
|
if (aValue === null || aValue === undefined) return 1
|
||||||
|
if (bValue === null || bValue === undefined) return -1
|
||||||
|
|
||||||
|
// 字符串比较
|
||||||
|
if (typeof aValue === 'string' && typeof bValue === 'string') {
|
||||||
|
return this.sortDirection === 'asc'
|
||||||
|
? aValue.localeCompare(bValue)
|
||||||
|
: bValue.localeCompare(aValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 数字比较
|
||||||
|
if (typeof aValue === 'number' && typeof bValue === 'number') {
|
||||||
|
return this.sortDirection === 'asc'
|
||||||
|
? aValue - bValue
|
||||||
|
: bValue - aValue
|
||||||
|
}
|
||||||
|
|
||||||
|
// 其他类型比较
|
||||||
|
return this.sortDirection === 'asc'
|
||||||
|
? String(aValue).localeCompare(String(bValue))
|
||||||
|
: String(bValue).localeCompare(String(aValue))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
},
|
||||||
// 内部实现前端分页逻辑
|
// 内部实现前端分页逻辑
|
||||||
tableData() {
|
tableData() {
|
||||||
return this.data.slice((this.pageNum - 1) * this.pageSize, this.pageNum * this.pageSize)
|
return this.processedData.slice((this.pageNum - 1) * this.pageSize, this.pageNum * this.pageSize)
|
||||||
},
|
},
|
||||||
// 计算总页数
|
// 计算总页数
|
||||||
totalPage() {
|
totalPage() {
|
||||||
return Math.ceil(this.data.length / this.pageSize)
|
return Math.ceil(this.processedData.length / this.pageSize)
|
||||||
},
|
},
|
||||||
// 计算总条数
|
// 计算总条数
|
||||||
total() {
|
total() {
|
||||||
return this.data.length
|
return this.processedData.length
|
||||||
},
|
},
|
||||||
// 是否展示分页组件
|
// 是否展示分页组件
|
||||||
showPagination() {
|
showPagination() {
|
||||||
@@ -116,7 +193,53 @@ export default {
|
|||||||
result += `${minutes}分钟`
|
result += `${minutes}分钟`
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
|
},
|
||||||
|
// 处理筛选条件变化
|
||||||
|
handleFilterChange() {
|
||||||
|
this.pageNum = 1
|
||||||
|
},
|
||||||
|
// 处理排序规则变化
|
||||||
|
handleSortChange() {
|
||||||
|
this.pageNum = 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.coil-table {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-controls {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filter-section,
|
||||||
|
.sort-section {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-pagination {
|
||||||
|
margin-top: 0px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 768px) {
|
||||||
|
.table-controls {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filter-section,
|
||||||
|
.sort-section {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user