🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] >[success] # 前端多条件筛选数据 ~~~ 需求:如下图,有'桥梁名称(字符串)'、'桥梁类型(数组)'、'桥梁分类(数组)'三个过滤条件用这'3'个 筛选条件'依次过滤'列表并且返回过滤后的结果,如果'桥梁名称'没有匹配到筛选结果返回'空数组','桥梁类型' 和'桥梁分类'就不继续进行筛选。 ~~~ ![](https://img.kancloud.cn/55/39/553949bdb4d800ea6a17ef85000e3e6b_317x656.png) <br/> >[success] ## 解决思路1(if深层嵌套) ~~~ 这个属于笨方法,思路:'if'判断'桥梁名称'有值,再在'if'中判断'桥梁类型'有值,再在'if'中判断 '桥梁分类'有值,反复'嵌套if' ~~~ JSON数据 ~~~ let bridgeDataArr = [{ "bridgeName": "桥梁1", "bridgeType": "混凝土梁式桥", "bridgeCategory": "特大桥", }, { "bridgeName": "桥梁2", "bridgeType": "钢梁桥", "bridgeCategory": "大桥", }, { "bridgeName": "桥梁3", "bridgeType": "悬索桥", "bridgeCategory": "中桥" }, { "bridgeName": "桥梁4", "bridgeType": "斜拉桥", "bridgeCategory": "小桥" }, { "bridgeName": "桥梁5", "bridgeType": "斜拉桥", "bridgeCategory": "涵洞" }] ~~~ JS代码 ~~~ // 筛选条件 let filterCondition = [ { bridgeName: '桥梁1', bridgeType: [], bridgeCategory: [] }, { bridgeName: '桥梁5', bridgeType: ['斜拉桥', '钢梁桥'], bridgeCategory: [] }, { bridgeName: '桥梁5', bridgeType: ['斜拉桥', '钢梁桥'], bridgeCategory: ['涵洞'] }, { bridgeName: '乱七八糟的桥梁', bridgeType: ['斜拉桥', '钢梁桥'], bridgeCategory: ['涵洞'] } ] // 最终过滤结果 let finalResults = [] // 过滤方法 function filterFun(data){ // 1 - 4的随机数 let num = Math.floor(Math.random()*4+1) // 桥梁名称有值 if(filterCondition[num].bridgeName){ // 桥梁类型有值 if(filterCondition[num].bridgeType.length > 0){ // 桥梁分类有值 if(filterCondition[num].bridgeCategory.length > 0){ ... } else { ... } } else { ... } } else { // 桥梁名称无值 // 桥梁类型有值 if(filterCondition[num].bridgeType.length > 0){ // 桥梁分类有值 if(filterCondition[num].bridgeCategory.length > 0){ ... } else { ... } } else { ... } } } filterFun(bridgeDataArr) ~~~ ~~~ 上面的写法虽然可以实现想要的过滤结果,但是'嵌套'过于复杂以后新'增加筛选条件'这里代码要发生 天翻地覆的变化。 ~~~ <br/> >[success] ## 解决思路2(解决if深层嵌套的问题) ~~~ 虽然这个方法可以解决,但是也是'野路子'判断,虽然说避免了'反复嵌套if'判断,把它修改成'同级'的'if'判断, 但是以后'新增过滤条件'后这里也会发生很大的变化。 ~~~ ~~~ // 过滤方法 function filterFun(data){ // 1 - 4的随机数 let num = Math.floor(Math.random()*4+1) // 桥梁名称、桥梁类型、桥梁分类有值 if(filterCondition[num].bridgeName && filterCondition[num].bridgeType.length > 0 && filterCondition[num].bridgeCategory.length > 0){ 三个条件过滤操作... } else if(filterCondition[num].bridgeName && filterCondition[num].bridgeType.length > 0){ // 桥梁名称、桥梁类型有值 过滤操作... } else if(filterCondition[num].bridgeName && filterCondition[num].bridgeCategory.length > 0){ // 桥梁名称、桥梁分类有值 过滤操作... } else if(filterCondition[num].bridgeType.length > 0 && filterCondition[num].bridgeCategory.length > 0){ // 桥梁类型、桥梁分类有值 过滤操作... } else if(filterCondition[num].bridgeName){ // 桥梁名称有值 过滤操作... } else if(filterCondition[num].bridgeType.length > 0){ // 桥梁类型有值 过滤操作... } else if(filterCondition[num].bridgeCategory){ // 桥梁分类有值 过滤操作... } } ~~~ <br/> >[success] ## 解决思路3 ~~~ 这种方法可以解决多种情况: 1. 无过滤条件时,只走'filterResultArr'赋值全部数据 2. '桥梁名称'有值用桥梁名称过滤后的结果,在'桥梁类型'、'桥梁分类'中继续来过滤,如果在'桥梁名称'这 过滤返回值为'空数组',就不会往下走 ~~~ ~~~ // 过滤方法 function filterFun(data){ let filterResultArr = [] // 最终过滤结果 let bridgeNameFilter = [] // 桥梁名称过滤结果 let bridgeTypeFilter = [] // 桥梁类型过滤结果 let bridgeCategoryFilter = [] // 桥梁分类过滤结果 if(data.length > 0){ // 项目下桥梁列表不为空 filterResultArr = data if(this.filterCondition.bridgeName){ // 桥梁名称有值 bridgeNameFilter = filterResultArr.filter(item => { return item.bridgeName.includes(this.filterCondition.bridgeName.toUpperCase()) }) filterResultArr = bridgeNameFilter } if(filterResultArr.length > 0 && this.filterCondition.bridgeType.length > 0){ // 桥梁类型有值 bridgeTypeFilter = filterResultArr.filter(item => { return this.filterCondition.bridgeType.some(ele => ele === item.bridgeType) }) filterResultArr = bridgeTypeFilter } if(filterResultArr.length > 0 && this.filterCondition.bridgeCategory.length > 0){ // 桥梁分类有值 bridgeCategoryFilter = filterResultArr.filter(item => { return this.filterCondition.bridgeCategory.some(ele => ele === item.bridgeCategory) }) filterResultArr = bridgeCategoryFilter } } // 返回最终过滤结果 return filterResultArr } ~~~ <br/> >[success] ## 1对多过滤 ~~~ 顾名思义'1对多',如下:我想根据输入结果去这3个条件(跨、部件、构件)中过滤出符合任意一个条件的结果 ~~~ ![](https://img.kancloud.cn/6c/93/6c93e5d39ff9b50a283566f4726cdd3c_342x43.png) 实现如下: ~~~ let value = '2' // 输入框值 let arr = [ // 要过滤的数据 { K: '第1跨', BJ: '部件1', GJ: '构件1' }, { K: '第2跨', BJ: '部件2', GJ: '构件2' } ] // 过滤条件 let isKorBJorGJ = item => item.K.includes(value) || item.BJ.includes(value) || item.BJ.includes(value) console.log(arr.filter(item => isKorBJorGJ(item))) // 第二跨 ~~~