Vue3中如何使用不同参数搜索对象数组 修复名称搜索返回undefined问题
问题根因
现有代码仅实现了ID匹配逻辑,未覆盖名称搜索场景,同时存在4个显性bug:
- getter内匹配逻辑硬编码为
cf.id === state.activeCaseFile,完全没有名称字段的判断分支,输入名称字符串时自然无法匹配数字类型的ID,返回undefined searchInput初始值设为数字0,输入名称得到的是字符串类型,和数字ID做全等判断时会因类型不匹配失效activeCaseFile初始值定义为数组,搜索时却直接赋值为输入的字符串/数字,数据类型混乱- 现有逻辑用
find仅返回第一条匹配结果,按名称搜索时存在同名多条数据的场景,单条返回逻辑不适用
修复方案
1. 调整Pinia Store代码
统一数据类型,新增搜索方式标记,补全名称匹配逻辑:
export const useCaseFileStore = defineStore('caseFile', { state: () => ({ matchingCaseFiles: [], // 搜索类型标记,可选值'id'/'name',切换搜索参数时同步更新该值 searchMethod: 'id', caseFiles: [ { name: 'John Cramer', id: 1111, title: 'test Files' }, { name: 'John Cramer', id: 11212, title: 'test fileTwo' } ], // 修正初始值类型,用于存储当前搜索关键词 activeCaseFile: null, }), actions: { searchByCf(searchQuery) { this.activeCaseFile = searchQuery; }, // 新增搜索方式切换方法,选择ID/NAME搜索参数时调用 setSearchMethod(method) { this.searchMethod = method; // 切换搜索方式时清空已有搜索关键词 this.activeCaseFile = null; } }, getters: { activeCaseFiles: (state) => { if (!state.activeCaseFile) return []; // 根据当前选中的搜索方式走对应匹配逻辑 if (state.searchMethod === 'id') { // 输入值转数字后再匹配ID,避免字符串型数字和数字ID全等判断失败 const targetId = Number(state.activeCaseFile); return state.caseFiles.filter(cf => cf.id === targetId); } else { // 名称搜索默认做不区分大小写的模糊匹配,需要精确匹配直接把includes改成===即可 const keyword = String(state.activeCaseFile).toLowerCase(); return state.caseFiles.filter(cf => cf.name.toLowerCase().includes(keyword)); } }, }, })
2. 调整搜索组件代码
修正输入初始值类型,绑定搜索方式切换逻辑:
<template> <!-- 搜索方式选择控件,绑定选中的搜索参数类型 --> <select v-model="searchMethod" class="select select-bordered select-sm"> <option value="id">按ID搜索</option> <option value="name">按名称搜索</option> </select> <input placeholder="Type here to start a search and press ENTER" class="input w-full input-bordered input-sm" v-model="searchInput" /> </template> <script setup> import { ref, watch } from 'vue'; import { useCaseFileStore } from '@/store/caseFile'; // 替换成实际store路径 const store = useCaseFileStore(); // 搜索输入初始值改为空字符串,不要设为数字0 const searchInput = ref(''); const searchMethod = ref('id'); // 监听搜索方式切换,同步更新store状态 watch(searchMethod, (newMethod) => { store.setSearchMethod(newMethod); searchInput.value = ''; }); watch(searchInput, (newVal) => { if(!newVal) { store.searchByCf(null); return; } store.searchByCf(newVal); }); </script>
补充说明
- 原逻辑用
find仅能获取第一条匹配数据,替换为filter可返回所有符合条件的结果,适配重名数据场景 - 值比较前统一做类型转换,避免字符串、数字类型不一致导致
===判断失效 - 不需要模糊匹配的话,直接把名称匹配逻辑里的
includes换成全等判断即可
内容的提问来源于stack exchange,提问作者seanberlin
相关产品推荐
相关产品推荐

