记录 vue 3 多联动筛选解决方案

在做后台表格页面时,经常遇到用户希望通过多个字段筛选数据的需求。

这种需求一开始看着不难,直接在 filter 里写一堆条件判断就行。但当字段一多,页面复用性一低,代码就容易一团乱麻。所以我干脆封了个小 hooks,叫做 useFilter,来处理这类 多条件筛选


核心逻辑:封装一个通用的 hooks

先看这个 useFilter.ts 文件,结构很简单但很实用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import {ref} from 'vue';

export function useFilter() {
const filteredData = ref([]);
const isEmpty = (val: any) =>
val === undefined || val === null || val === '';

const filterData = (data, filters) => {
filteredData.value = data.filter(item => {
return Object.entries(filters).every(([field, filterValue]) => {
if (isEmpty(filterValue)) return true; // 忽略空值
const itemValue = item[field];
return itemValue?.toString().includes(filterValue.toString());
});
});
};

return {
filteredData,
filterData
};
}

这里的核心思想就是:

你传一堆筛选条件过来:

  • 每条数据都对这些条件 every 一下;

  • 条件为空就跳过,不做判断;

  • 有值的字段,就做一个字符串的包含判断。

这样做的好处是:不管你有几个筛选字段,都能通吃。不用再在组件里写一堆 if elsev-if 去控制筛选逻辑。

页面中怎么用?

再来看页面这块,实际调用就很简单了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const {filteredData, filterData} = useFilter();

const handleFilterData = async () => {
const filters = {
name: formValue.value.name, // 姓名
age: formValue.value.age, // 年龄
gender: formValue.value.gender, // 性别
personality: formValue.value.personality,// 性格
profession: formValue.value.profession, // 职业
hobby: formValue.value.hobby // 爱好
};

await nextTick();
filterData(tableDataMock.value, filters); // 使用 hook 筛选
data.value = filteredData.value;// 显示到页面
}
  • 筛选条件可以来自用户选的树、表单、tab栏等等。

  • 调用 filterData() 就筛好了。

  • 最后把 filteredData 赋值给你展示用的 data 即可。

这个方法的优点?

  • ✅ 复用性强:一次封装,多处使用,后期维护很省心。

  • ✅ 字段灵活:字段变动无需改逻辑,直接传参就能筛。

  • ✅ 逻辑清晰:不用在组件中堆砌一堆筛选判断。

对于中后台项目来说,尤其适合那种字段不固定、筛选项灵活的场景。

有什么局限吗?

当然也有:

  • ❌ 只能做模糊匹配:目前只做了 includes,如果你想做范围筛选(比如数字区间、日期区间)就得扩展一下。

  • ❌ 性能问题:数据量特别大的时候,纯前端筛选效率肯定不如后端接口查询(比如上千条数据),建议还是让后端干。

  • ❌ 数据类型未处理:目前所有字段默认转字符串比对,对布尔、数字、枚举等类型没有做特殊处理。

适用场景:

这套方案特别适合中小数据量的业务页面,比如:

  • 列表页的多条件本地筛选

  • 管理后台的数据面板

  • 页面内多级联动的过滤逻辑

如果你们的系统数据量不大,或者暂时不想为每个筛选条件都跑一趟后端,那这个 hooks 用起来会非常省事。