vxe-table动态列筛选以及筛选项动态变化的问题及解决

 更新时间:2025年04月24日 09:25:04   作者:吃面必吃蒜  
这篇文章主要介绍了vxe-table动态列筛选以及筛选项动态变化的问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

vxe-table动态列筛选以及筛选项动态变化

需求场景

  1. table 的列是由接口动态返回的;
  2. 列的筛选项就是数据的值,比如【姓名】这个字段总共有三个值,那么姓名这一列的筛选项就是这三个值本身;
  3. 当有一列筛选后,其他列的筛选项也要动态变化。

vxe-table 版本:4.9.14

完整代码

vue template 部分:

<vxe-table
   ref="vxeTableRef"
   :data="state.tableData"
   height="100%"
   border
   @filter-change="handleFilterChange"
 >
   <vxe-column
     v-for="colOpt in columnsOptions"
     :key="colOpt.field"
     :field="colOpt.field"
     :title="colOpt.title"
     align="center"
     resizable
     sortable
     :filters="colOpt.filters"
     :filter-method="colOpt.filterMethod"
   />
 </vxe-table>

script 部分:

<script setup lang="ts">
// 其他代码
const vxeTableRef = ref();

const handleSearch = () => {
	// 获取table数据部分的逻辑
	API(params).then((res: any) => {
	    // ...
	    state.tableData = data || [];
	    if (state.tableData.length > 0) {
	      // 在数据加载后重置所有筛选
	      nextTick(() => {
	        if (vxeTableRef.value) {
	          vxeTableRef.value.clearFilter();
	        }
	      });
	    }
  });
}

// 下面是处理列筛选的逻辑
// 获取筛选选项
const getColumnFilters = (column: string) => {
  // 使用 Map 来提高性能
  const uniqueMap = new Map();

  for (const row of state.tableData) {
    const value = row[column];
    if (!uniqueMap.has(value)) {
      uniqueMap.set(value, {
        label: value == null || value == "" ? "(空)" : String(value),
        value: value,
        checked: false
      });
    }
  }

  return Array.from(uniqueMap.values());
};

// 创建筛选方法
const createFilterMethod = (column: string) => {
  return ({ value, row }: { value: any; row: any }) => {
    const cellValue = row[column];

    // 处理空值的情况
    if (value === null || value === "") {
      return cellValue === null || cellValue === "";
    }

    // 如果单元格值是数字,进行数字比较
    if (typeof cellValue === "number") {
      return cellValue === Number(value);
    }

    // 默认进行字符串比较
    return String(cellValue) === String(value);
  };
};

// 数据是异步加载的,使用计算属性来处理列配置
const columnsOptions = computed(() => {
  return state.columns.map(col => ({
    field: col,
    title: col,
    filters: getColumnFilters(col),
    filterMethod: createFilterMethod(col)
  }));
});

// 处理筛选变化
const handleFilterChange = (params: any) => {
  // 获取当前表格中可见的行数据
  const { filterList } = params;
  // 如果没有筛选项,就刷新
  if (!filterList || filterList.length === 0) {
    handleSearch();
  }

  // 筛选已经应用,获取处理后的可见数据
  const visibleData = vxeTableRef.value?.getTableData().visibleData || [];

  // 获取当前被筛选的列,避免修改它们的筛选项
  const filteredColumns = new Set(filterList.map((item: any) => item.field));

  // 更新筛选状态
  nextTick(() => {
    // 只更新未被筛选的列
    state.columns.forEach(column => {
      // 跳过当前正在筛选的列
      if (filteredColumns.has(column)) return;

      // 为此列生成新的筛选选项,但仅从可见数据中获取
      const uniqueMap = new Map();
      for (const row of visibleData) {
        const value = row[column];
        if (!uniqueMap.has(value)) {
          uniqueMap.set(value, {
            label: value == null || value === "" ? "(空)" : String(value),
            value: value,
            checked: false
          });
        }
      }

      // 更新此列的筛选项
      if (vxeTableRef.value) {
        vxeTableRef.value.setFilter(column, Array.from(uniqueMap.values()));
      }
    });
  });
};
</script>

里面关键的一个点在于,vxe-table 筛选后的展示数据跟我们的源数据是分开的,所以筛选触发的事件中,我们应该拿 visibleData 来做筛选项的动态处理。

由于逻辑可复用,所以记录一下,需要用的时候直接copy就好了。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • vue表单验证rules及validator验证器的使用方法实例

    vue表单验证rules及validator验证器的使用方法实例

    在vue开发中,难免遇到各种表单校验,下面这篇文章主要给大家介绍了关于vue表单验证rules及validator验证器使用的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2022-07-07
  • Vue CLI3中使用compass normalize的方法

    Vue CLI3中使用compass normalize的方法

    这篇文章主要介绍了Vue CLI3中使用compass normalize的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-05-05
  • 前端笔记之vue中Map、Set之间的使用和区别详析

    前端笔记之vue中Map、Set之间的使用和区别详析

    Vue中的Map格式,是一种用于存储和管理键值对数据的集合,与常规的数组不同,Map提供了更灵活和高效的方式来操作数据,这篇文章主要介绍了前端笔记之vue中Map、Set之间的使用和区别的相关资料,需要的朋友可以参考下
    2025-11-11
  • Vue使用自定义指令打开dialog的实现方法

    Vue使用自定义指令打开dialog的实现方法

    在web后台管理项目中,经常要用到dialog,就vue来说,使用方式则是引入组件,注册,在template中使用,试想一下,如果我们需要在项目中的不同.vue文件中使用该dialog,但是又不想每次都在template中写入组件该如何实现呢?本文我们介绍用指令控制dialog,需要的朋友可以参考下
    2024-07-07
  • Vue组件化常用方法之组件传值与通信

    Vue组件化常用方法之组件传值与通信

    这篇文章主要给大家介绍了关于Vue组件化常用方法之组件传值与通信的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03
  • Vue常用指令V-model用法

    Vue常用指令V-model用法

    本篇文章主要介绍了Vue常用指令_V-model用法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-03-03
  • 详解vue的hash跳转原理

    详解vue的hash跳转原理

    这篇文章主要介绍了vue的hash跳转原理,帮助大家更好的理解和学习使用vue框架,感兴趣的朋友可以了解下
    2021-03-03
  • vue中将网页打印成pdf实例代码

    vue中将网页打印成pdf实例代码

    本篇文章主要介绍了vue中将网页打印成pdf实例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-06-06
  • vue-router嵌套路由方式(页面路径跳转但页面显示空白)

    vue-router嵌套路由方式(页面路径跳转但页面显示空白)

    这篇文章主要介绍了vue-router嵌套路由方式(页面路径跳转但页面显示空白),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-04-04
  • Vue3中Watch、Watcheffect、Computed的使用和区别解析

    Vue3中Watch、Watcheffect、Computed的使用和区别解析

    Watch、Watcheffect、Computed各有优劣,选择使用哪种方法取决于应用场景和需求,watch 适合副作用操作,watchEffect适合简单的自动副作用管理,computed 适合声明式的派生状态计算,本文通过场景分析Vue3中Watch、Watcheffect、Computed的使用和区别,感兴趣的朋友一起看看吧
    2024-07-07

最新评论