vxe-table筛选功能深度解析:从基础筛选到高级查询

vxe-table筛选功能深度解析:从基础筛选到高级查询

【免费下载链接】vxe-table vxe-table vue 表单/表格解决方案 【免费下载链接】vxe-table 项目地址: https://gitcode.com/gh_mirrors/vx/vxe-table

你是否还在为复杂数据表格的筛选功能实现而烦恼?从简单的列筛选到多条件组合查询,从客户端本地筛选到服务端高效过滤,vxe-table提供了一套完整的解决方案。本文将带你全面掌握vxe-table筛选功能的实现原理与使用技巧,读完后你将能够:

  • 快速配置基础筛选功能(单选/多选筛选)
  • 实现自定义筛选逻辑与高级过滤
  • 掌握筛选状态管理与性能优化策略
  • 解决复杂场景下的筛选需求(如日期范围、远程筛选)

一、筛选功能架构解析

vxe-table的筛选系统采用模块化设计,主要由筛选钩子(hook.ts)、筛选面板(panel.ts)和核心处理逻辑三部分组成。其整体架构如下:

mermaid

核心处理流程

筛选功能的核心处理流程可分为四个阶段:

mermaid

二、基础筛选实现

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>

筛选状态管理流程如下:

mermaid

三、高级筛选功能

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>

自定义筛选面板的工作原理:

mermaid

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>

远程筛选的最佳实践:

  1. 筛选状态本地缓存:避免重复请求相同筛选条件
  2. 筛选选项动态加载:仅在打开筛选面板时加载选项数据
  3. 筛选参数合并:合并多个列的筛选条件后一次性请求
  4. 筛选状态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筛选功能未来可探索的方向:

  1. 智能筛选推荐:基于用户筛选历史推荐常用筛选条件
  2. 筛选模板保存:允许用户保存常用筛选条件组合
  3. 多维度筛选可视化:使用图表展示筛选结果分布
  4. AI辅助筛选:通过自然语言处理将用户输入转换为筛选条件

通过本文的介绍,相信你已经掌握了vxe-table筛选功能的核心用法和高级技巧。合理利用这些功能,可以为用户提供强大而直观的数据筛选体验,大幅提升数据处理效率。

如有任何问题或建议,欢迎在项目仓库提交issue或PR参与贡献!

扩展学习资源

  • vxe-table官方文档:筛选功能章节
  • 示例项目:vxe-table-demo中的筛选功能演示
  • 源码解析:packages/table/module/filter目录下的实现

【免费下载链接】vxe-table vxe-table vue 表单/表格解决方案 【免费下载链接】vxe-table 项目地址: https://gitcode.com/gh_mirrors/vx/vxe-table

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值