vxe-table筛选功能深度解析:从基础筛选到高级查询
【免费下载链接】vxe-table vxe-table vue 表单/表格解决方案 项目地址: https://gitcode.com/gh_mirrors/vx/vxe-table
你是否还在为复杂数据表格的筛选功能实现而烦恼?从简单的列筛选到多条件组合查询,从客户端本地筛选到服务端高效过滤,vxe-table提供了一套完整的解决方案。本文将带你全面掌握vxe-table筛选功能的实现原理与使用技巧,读完后你将能够:
- 快速配置基础筛选功能(单选/多选筛选)
- 实现自定义筛选逻辑与高级过滤
- 掌握筛选状态管理与性能优化策略
- 解决复杂场景下的筛选需求(如日期范围、远程筛选)
一、筛选功能架构解析
vxe-table的筛选系统采用模块化设计,主要由筛选钩子(hook.ts)、筛选面板(panel.ts)和核心处理逻辑三部分组成。其整体架构如下:
核心处理流程
筛选功能的核心处理流程可分为四个阶段:
二、基础筛选实现
2.1 快速配置单选/多选筛选
vxe-table提供了两种基础筛选模式:单选筛选和多选筛选。通过简单配置即可实现这两种筛选功能。
2.1.1 单选筛选(性别筛选示例)
<vxe-table :data="tableData">
<!-- 其他列配置 -->
<vxe-column
field="sex"
title="性别"
:filters="sexFilters"
:filter-multiple="false" <!-- 单选模式 -->
:formatter="formatterSex"
></vxe-column>
</vxe-table>
<script setup>
const sexFilters = [
{ label: '女', value: '0' },
{ label: '男', value: '1' }
]
const formatterSex = ({ cellValue }) => {
return cellValue === '0' ? '女' : '男'
}
</script>
2.1.2 多选筛选(年龄区间筛选示例)
<vxe-column
field="age"
title="年龄"
sortable
:filters="ageOptions"
:filter-multiple="true" <!-- 多选模式 -->
></vxe-column>
<script setup>
const ageOptions = [
{ label: '20岁以下', value: 20 },
{ label: '20-30岁', value: 30 },
{ label: '30-40岁', value: 40 },
{ label: '40岁以上', value: 100 }
]
</script>
2.2 筛选面板核心UI结构
筛选面板的DOM结构由三个主要部分组成:表头、选项列表和操作按钮区:
<div class="vxe-table--filter-wrapper">
<!-- 表头区域 -->
<ul class="vxe-table--filter-header">
<li class="vxe-table--filter-option">
<span class="vxe-checkbox--icon"></span>
<span class="vxe-checkbox--label">全选</span>
</li>
</ul>
<!-- 选项列表区域 -->
<ul class="vxe-table--filter-body">
<li class="vxe-table--filter-option is--checked">
<span class="vxe-checkbox--icon"></span>
<span class="vxe-checkbox--label">20岁以下</span>
</li>
<!-- 更多选项 -->
</ul>
<!-- 操作按钮区域 -->
<div class="vxe-table--filter-footer">
<button>确定</button>
<button>重置</button>
</div>
</div>
2.3 基础API使用
vxe-table提供了丰富的API用于操作筛选状态:
| 方法名 | 描述 | 参数 |
|---|---|---|
| openFilter | 手动打开筛选面板 | fieldOrColumn: 列名或列配置 |
| setFilter | 设置筛选条件 | fieldOrColumn, options, isUpdate |
| clearFilter | 清除筛选条件 | fieldOrColumn(可选) |
| getCheckedFilters | 获取所有选中的筛选条件 | - |
| saveFilterPanel | 保存筛选面板状态 | - |
| resetFilterPanel | 重置筛选面板 | - |
示例:手动控制筛选状态
// 打开指定列的筛选面板
tableRef.value.openFilter('age')
// 设置筛选条件并立即应用
tableRef.value.setFilter('sex', [
{ label: '男', value: '1', checked: true }
], true)
// 获取当前所有筛选条件
const filters = tableRef.value.getCheckedFilters()
console.log('当前筛选条件:', filters)
// 清除所有筛选条件
tableRef.value.clearFilter()
二、基础筛选功能实现
2.1 快速开始:默认筛选配置
vxe-table的筛选功能设计遵循"约定优于配置"原则,只需简单几步即可实现基础筛选:
<template>
<vxe-table :data="tableData">
<!-- 基础文本筛选 -->
<vxe-column field="name" title="姓名"></vxe-column>
<!-- 单选筛选 -->
<vxe-column
field="sex"
title="性别"
:filters="sexFilters"
:filter-multiple="false"
:formatter="formatSex">
</vxe-column>
<!-- 多选筛选 -->
<vxe-column
field="age"
title="年龄"
:filters="ageFilters"
:filter-multiple="true">
</vxe-column>
</vxe-table>
</template>
<script setup>
import { ref } from 'vue'
const tableData = ref([
{ id: 1, name: '张三', sex: '1', age: 28 },
{ id: 2, name: '李四', sex: '1', age: 22 },
{ id: 3, name: '王五', sex: '0', age: 32 },
// 更多数据...
])
// 性别筛选选项
const sexFilters = ref([
{ label: '男', value: '1' },
{ label: '女', value: '0' }
])
// 年龄筛选选项
const ageFilters = ref([
{ label: '20-29岁', value: '20-29' },
{ label: '30-39岁', value: '30-39' },
{ label: '40岁以上', value: '40+' }
])
// 格式化性别显示
const formatSex = ({ cellValue }) => {
return cellValue === '1' ? '男' : '女'
}
</script>
上述代码实现了一个包含两种筛选模式的表格:
- 性别列:单选筛选(只能选择男或女)
- 年龄列:多选筛选(可同时选择多个年龄段)
2.2 筛选事件与状态管理
筛选系统会触发多种事件,可用于跟踪和响应筛选状态变化:
<vxe-table
:data="tableData"
@filter-change="handleFilterChange"
@filter-visible="handleFilterVisible"
>
<!-- 列配置 -->
</vxe-table>
<script setup>
// 筛选条件变化时触发
const handleFilterChange = (params) => {
console.log('筛选条件变化:', params)
// params结构: { column, field, values, datas, filters }
// 可在此处处理筛选后的业务逻辑
// 如更新URL参数、保存用户筛选偏好等
}
// 筛选面板显示/隐藏时触发
const handleFilterVisible = ({ visible, column }) => {
console.log(`列[${column.field}]筛选面板${visible ? '显示' : '隐藏'}`)
}
</script>
筛选状态管理流程如下:
三、高级筛选功能
3.1 自定义筛选方法
当内置筛选逻辑无法满足需求时,可通过filter-method自定义筛选逻辑:
<vxe-column
field="age"
title="年龄"
:filters="ageFilters"
:filter-method="filterAgeMethod">
</vxe-column>
<script setup>
// 自定义年龄筛选逻辑
const filterAgeMethod = ({ value, row }) => {
// value: 选中的筛选值
// row: 当前行数据
// 示例: 实现"大于指定年龄"的筛选逻辑
return row.age >= value
}
// 筛选选项
const ageFilters = [
{ label: '大于20岁', value: 20 },
{ label: '大于30岁', value: 30 },
{ label: '大于40岁', value: 40 }
]
</script>
高级应用:范围筛选实现
<vxe-column
field="score"
title="成绩"
:filters="scoreFilters"
:filter-method="filterScoreRange">
</vxe-column>
<script setup>
// 范围筛选实现
const filterScoreRange = ({ value, row }) => {
const [min, max] = value
return row.score >= min && row.score <= max
}
// 成绩范围筛选选项
const scoreFilters = [
{ label: '60分以下', value: [0, 59] },
{ label: '60-80分', value: [60, 80] },
{ label: '80-100分', value: [80, 100] }
]
</script>
3.2 自定义筛选面板
对于复杂筛选场景,可通过filter-render自定义筛选面板内容:
<vxe-column
field="date"
title="日期"
:filter-render="{ name: 'MyDateRangeFilter' }">
</vxe-column>
<script setup>
import { defineComponent } from 'vue'
// 定义日期范围筛选组件
const MyDateRangeFilter = defineComponent({
props: {
options: Array,
column: Object,
$table: Object
},
setup (props) {
const dateRange = ref(['', ''])
const confirm = () => {
// 调用表格的筛选方法应用筛选
props.$table.saveFilterPanelByEvent()
// 这里可以添加自定义逻辑
}
return {
dateRange,
confirm
}
},
template: `
<div class="date-range-filter">
<el-date-picker
v-model="dateRange"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期">
</el-date-picker>
<button @click="confirm">确认筛选</button>
</div>
`
})
// 注册自定义筛选组件
VxeUI.renderer.add('MyDateRangeFilter', MyDateRangeFilter)
</script>
自定义筛选面板的工作原理:
3.3 远程筛选实现
在处理大数据集时,客户端筛选可能导致性能问题,此时应使用远程筛选(服务端筛选):
<vxe-table
:data="tableData"
:loading="loading"
:filter-config="{ remote: true }"
@filter-change="handleRemoteFilter"
>
<vxe-column
field="name"
title="姓名"
:filters="[{data: []}]" <!-- 动态加载选项 -->
:filter-multiple="true">
</vxe-column>
<!-- 其他列 -->
</vxe-table>
<script setup>
const tableData = ref([])
const loading = ref(false)
const filterForm = ref({})
// 远程筛选处理
const handleRemoteFilter = async (params) => {
// 保存当前筛选条件
filterForm.value[params.field] = params.values
// 显示加载状态
loading.value = true
try {
// 调用API获取筛选后的数据
const response = await api.get('/data/list', {
params: filterForm.value
})
// 更新表格数据
tableData.value = response.data.records
} finally {
loading.value = false
}
}
// 初始加载筛选选项(如异步获取可选列表)
onMounted(async () => {
const { data } = await api.get('/filter-options', { params: { field: 'name' } })
// 更新筛选选项
tableRef.value.setFilter('name', data.options)
})
</script>
远程筛选的最佳实践:
- 筛选状态本地缓存:避免重复请求相同筛选条件
- 筛选选项动态加载:仅在打开筛选面板时加载选项数据
- 筛选参数合并:合并多个列的筛选条件后一次性请求
- 筛选状态URL同步:将筛选条件编码到URL中,支持页面刷新后恢复筛选状态
四、筛选功能进阶技巧
4.1 筛选状态持久化
实现筛选状态的保存与恢复,提升用户体验:
// 保存筛选状态到本地存储
const saveFilterState = () => {
const filters = tableRef.value.getCheckedFilters()
localStorage.setItem('table-filters', JSON.stringify(filters))
}
// 从本地存储恢复筛选状态
const restoreFilterState = async () => {
const savedFilters = localStorage.getItem('table-filters')
if (savedFilters) {
const filters = JSON.parse(savedFilters)
// 逐个恢复筛选条件
for (const filter of filters) {
await tableRef.value.setFilter(filter.field, filter.values)
}
}
}
// 在合适的时机调用
onMounted(() => {
restoreFilterState()
})
// 在筛选变化时保存
const handleFilterChange = () => {
saveFilterState()
}
4.2 复杂多条件组合筛选
对于复杂业务场景,可能需要实现多条件组合筛选面板:
<template>
<div class="advanced-filter">
<el-button @click="showFilterPanel = true">高级筛选</el-button>
<el-dialog v-model="showFilterPanel" title="高级筛选">
<el-form :model="filterForm" inline>
<el-form-item label="姓名">
<el-input v-model="filterForm.name"></el-input>
</el-form-item>
<el-form-item label="性别">
<el-select v-model="filterForm.sex" multiple>
<el-option label="男" value="1"></el-option>
<el-option label="女" value="0"></el-option>
</el-select>
</el-form-item>
<el-form-item label="年龄范围">
<el-input-number v-model="filterForm.ageMin"></el-input-number>
<span>至</span>
<el-input-number v-model="filterForm.ageMax"></el-input-number>
</el-form-item>
</el-form>
<div slot="footer">
<el-button @click="resetFilter">重置</el-button>
<el-button type="primary" @click="applyFilter">应用筛选</el-button>
</div>
</el-dialog>
<vxe-table ref="tableRef" :data="tableData"></vxe-table>
</div>
</template>
<script setup>
const showFilterPanel = ref(false)
const filterForm = ref({})
const tableRef = ref()
// 应用高级筛选
const applyFilter = () => {
// 清除现有筛选
tableRef.value.clearFilter()
// 应用姓名筛选(自定义筛选逻辑)
if (filterForm.value.name) {
tableRef.value.setFilter('name', [
{
label: `包含: ${filterForm.value.name}`,
value: filterForm.value.name,
checked: true
}
], true)
}
// 应用性别筛选
if (filterForm.value.sex?.length) {
const options = filterForm.value.sex.map(v => ({
label: v === '1' ? '男' : '女',
value: v,
checked: true
}))
tableRef.value.setFilter('sex', options, true)
}
// 关闭面板
showFilterPanel.value = false
}
// 重置筛选条件
const resetFilter = () => {
filterForm.value = {}
tableRef.value.clearFilter()
}
</script>
4.3 筛选性能优化
当表格数据量大或筛选逻辑复杂时,可采用以下优化策略:
1. 筛选缓存机制
// 实现筛选结果缓存
const filterCache = new Map()
const handleFilterChange = (params) => {
// 生成缓存键(基于筛选条件)
const cacheKey = JSON.stringify(params)
// 如果缓存存在则直接使用
if (filterCache.has(cacheKey)) {
tableData.value = filterCache.get(cacheKey)
return
}
// 否则执行筛选逻辑
const filteredData = originalData.filter(row => {
// 筛选逻辑
})
// 缓存筛选结果
filterCache.set(cacheKey, filteredData)
tableData.value = filteredData
}
2. 虚拟滚动与筛选结合
对于超大数据集(10万+记录),建议结合虚拟滚动使用筛选:
<vxe-table
:data="tableData"
:scroll-y="{ enabled: true, gt: 600 }"
:filter-config="{ remote: true }"
@filter-change="handleRemoteFilter"
>
<!-- 列配置 -->
</vxe-table>
3. 筛选条件节流处理
import { throttle } from 'lodash'
// 节流处理筛选事件(500ms内只执行一次)
const throttledFilter = throttle((params) => {
// 筛选逻辑
}, 500)
const handleFilterChange = (params) => {
throttledFilter(params)
}
五、常见问题与解决方案
5.1 筛选状态与表格数据同步问题
问题:使用setFilter后表格数据未立即更新
解决方案:确保设置isUpdate参数为true,或手动调用更新方法
// 错误方式
tableRef.value.setFilter('sex', [{ value: '1', checked: true }])
// 正确方式
tableRef.value.setFilter('sex', [{ value: '1', checked: true }], true)
// 或
tableRef.value.setFilter('sex', [{ value: '1', checked: true }])
tableRef.value.updateData() // 手动更新数据
5.2 自定义筛选面板样式问题
问题:自定义筛选面板样式与主题不统一
解决方案:使用vxe-table提供的CSS变量或自定义主题类
/* 自定义筛选面板样式 */
.vxe-table--filter-wrapper {
--vxe-font-size: 14px;
--vxe-table-filter-option-height: 36px;
--vxe-table-filter-bg-color: #fff;
--vxe-table-filter-border-color: #e8e8e8;
}
/* 自定义选项样式 */
.vxe-table--filter-option.is--checked {
background-color: #f5f8ff;
color: #1890ff;
}
5.3 复杂筛选条件的组合问题
问题:多列筛选条件之间的关系处理
解决方案:使用筛选事件统一处理多列筛选逻辑
const handleFilterChange = (params) => {
// 获取所有筛选条件
const allFilters = tableRef.value.getCheckedFilters()
// 构建复合筛选条件
const filterConditions = allFilters.reduce((conditions, item) => {
conditions[item.field] = item.values
return conditions
}, {})
// 应用复合筛选逻辑
applyComplexFilter(filterConditions)
}
// 实现复杂筛选逻辑
const applyComplexFilter = (conditions) => {
// 自定义多条件组合逻辑
tableData.value = originalData.filter(row => {
// 例如:满足所有条件(AND关系)
return Object.entries(conditions).every(([field, values]) => {
// 根据字段类型应用不同的筛选逻辑
if (field === 'age') {
return row.age >= Math.min(...values)
}
// 其他字段逻辑
})
})
}
六、总结与最佳实践
6.1 筛选功能使用建议
根据不同场景选择合适的筛选方式:
| 场景 | 推荐筛选方式 | 性能考量 |
|---|---|---|
| 简单列表(<1000条) | 客户端基础筛选 | 无需额外优化 |
| 中等数据集(1000-10000条) | 客户端自定义筛选 + 缓存 | 建议使用筛选结果缓存 |
| 大数据集(>10000条) | 服务端远程筛选 | 必须使用远程筛选 |
| 复杂条件筛选 | 高级筛选面板 + 远程筛选 | 结合筛选条件缓存 |
6.2 筛选功能开发 checklist
- 基础筛选功能实现(单选/多选)
- 自定义筛选逻辑(filter-method)
- 筛选状态管理(保存/恢复/清除)
- 筛选事件处理(filter-change)
- 响应式样式适配
- 性能优化(缓存/节流/远程筛选)
- 筛选状态持久化(可选)
- 筛选交互体验优化(动画/加载状态)
6.3 高级应用展望
vxe-table筛选功能未来可探索的方向:
- 智能筛选推荐:基于用户筛选历史推荐常用筛选条件
- 筛选模板保存:允许用户保存常用筛选条件组合
- 多维度筛选可视化:使用图表展示筛选结果分布
- AI辅助筛选:通过自然语言处理将用户输入转换为筛选条件
通过本文的介绍,相信你已经掌握了vxe-table筛选功能的核心用法和高级技巧。合理利用这些功能,可以为用户提供强大而直观的数据筛选体验,大幅提升数据处理效率。
如有任何问题或建议,欢迎在项目仓库提交issue或PR参与贡献!
扩展学习资源:
- vxe-table官方文档:筛选功能章节
- 示例项目:vxe-table-demo中的筛选功能演示
- 源码解析:packages/table/module/filter目录下的实现
【免费下载链接】vxe-table vxe-table vue 表单/表格解决方案 项目地址: https://gitcode.com/gh_mirrors/vx/vxe-table
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



