基于JavaScript实现前端数据多条件筛选功能


Posted in Javascript onAugust 19, 2020

有时候也会需要在前端进行数据筛选,增强交互体验。当数据可用的筛选条件较多时,把逻辑写死会给后期维护带来很大麻烦。下面是我自己写的一个简单的筛选器,筛选条件可以根据数据包含的字段动态设置。

仿照京东的筛选条件,这里就取价格区间和品牌作为测试。

基于JavaScript实现前端数据多条件筛选功能

代码

代码中主要使用js的过滤器Array.prototype.filter,该方法会对数组元素进行遍历检查,返回一个符合检查条件的新数组,不会改变原数组。

// filter()
var foo = [0,1,2,3,4,5,6,7,8,9];

var foo1 = foo.filter(
 function(item) {
 return item >= 5
 }
);

console.log(foo1); // [5, 6, 7, 8, 9]

有了这个方法,筛选数据方便了很多,下面先定义一个商品类。

// 定义商品类
function Product(name, brand, price) {
 this.name = name; // 名称
 this.brand = brand; // 品牌
 this.price = price; // 价格
}

创建一个过滤器对象,把所有过滤数据的方法放在里面。为了能自动适配不同的筛选条件,将筛选条件分为两个大类,一个是区间类型rangesFilter ,如:品牌、内存等;一个是选择类型choosesFilter,如:价格、屏幕尺寸等。

不同大类同时筛选时,进行的是与逻辑,每个大类在上一个大类筛选结果上进行筛选。比如我要筛选2000-5000块的华为手机,先调用rangesFilter筛选products并返回结果result1,然后用choosesFilter筛选result1并返回结果resulte2。

当然,如果还有其它大类,不一定是与逻辑,再另行处理。

// 商品筛选器
const ProductFilters = {
 /**
 * 区间类型筛选
 * @param {array<Product>} products
 * @param {array<{type: String, low: number, high: number}>} ranges
 */
 rangesFilter: function (products, ranges) { }

 /**
 * 选择类型筛选
 * @param {array<Product>} products
 * @param {array<{type: String, value: String}>} chooses
 */
 choosesFilter: function (products, chooses) { }
}

区间类型的筛选,代码如下。

// 区间类型条件结构
ranges: [
 {
  type: 'price', // 筛选类型/字段
  low: 3000, // 最小值
  high: 6000 // 最大值
 }
 ]
/**
 * @param {array<Product>} products
 * @param {array<{type: String, low: number, high: number}>} ranges
 */
 rangesFilter: function (products, ranges) {
 if (ranges.length === 0) {
  return products;
 } else {
  /**
  * 循环多个区间条件,
  * 每种区间类型应该只有一个,
  * 比如价格区间不会有1000-2000和4000-6000同时需要的情况
  */
  for (let range of ranges) {
  // 多个不同类型区间是与逻辑,可以直接赋值给自身
  products = products.filter(function (item) {
   return item[range.type] >= range.low && item[range.type] <= range.high;
  });
  }
  return products;
 }
 }

选择类型筛选:

// 选择类型条件结构
chooses: [
 {
  type: 'brand',
  value: '华为'
 },
 {
  type: 'brand',
  value: '苹果'
 }
 ]
/**
 * @param {array<Product>} products
 * @param {array<{type: String, value: String}>} chooses
 */
 choosesFilter: function (products, chooses) {
 let tmpProducts = [];
 if (chooses.length === 0) {
  tmpProducts = products;
 } else {
  /**
  * 选择类型条件是或逻辑,使用数组连接concat
  */
  for (let choice of chooses) {
  tmpProducts = tmpProducts.concat(products.filter(function (item) {
   return item[choice.type].indexOf(choice.value) !== -1;
  }));
  }
 }
 return tmpProducts;
 }

定义一个执行函数doFilter()。

function doFilter(products, conditions) {
 // 根据条件循环调用筛选器里的方法
 for (key in conditions) {
 // 判断是否有需要的过滤方法
 if (ProductFilters.hasOwnProperty(key + 'Filter') && typeof ProductFilters[key + 'Filter'] === 'function') {
  products = ProductFilters[key + 'Filter'](products, Conditions[key]);
 }
 }
 return products;
}
// 将两种大类的筛选条件放在同一个对象里
let Conditions = {
 ranges: [
 {
  type: 'price',
  low: 3000,
  high: 6000
 }
 ],
 chooses: [
 {
  type: 'brand',
  value: '华为'
 }
 ]
}

测试

创建10个商品数据,以及筛选条件

// 商品数组
const products = [
 new Product('华为荣耀9', '华为', 2299),
 new Product('华为P10', '华为', 3488),
 new Product('小米MIX2', '小米', 3599),
 new Product('小米6', '小米', 2499),
 new Product('小米Note3', '小米', 2499),
 new Product('iPhone7 32G', '苹果', 4588),
 new Product('iPhone7 Plus 128G', '苹果', 6388),
 new Product('iPhone8', '苹果', 5888),
 new Product('三星Galaxy S8', '三星', 5688),
 new Product('三星Galaxy S7 edge', '三星', 3399),
];
// 筛选条件
let Conditions = {
 ranges: [
 {
  type: 'price',
  low: 3000,
  high: 6000
 }
 ],
 chooses: [
 {
  type: 'brand',
  value: '华为'
 },
 {
  type: 'brand',
  value: '苹果'
 }
 ]
}

调用函数

let result = doFilter(products, Conditions);
console.log(result);

输出

基于JavaScript实现前端数据多条件筛选功能

代码的扩展性和可维护性都很好,只要保证筛选条件中的type字段在商品数据中一致都可以筛选,比如将筛选条件改为

let Conditions = {
 ranges: [
 {
  type: 'price',
  low: 3000,
  high: 6000
 }
 ],
 chooses: [
 {
  type: 'name',
  value: 'iPhone'
 }
 ]
}

输出

基于JavaScript实现前端数据多条件筛选功能

搜索匹配等一些地方也需要优化,是否区分大小写、是完全匹配还是模糊匹配等。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
(仅IE下有效)关于checkbox 三态
May 12 Javascript
谈谈JavaScript自定义回调函数
Oct 18 Javascript
javascript中FOREACH数组方法使用示例
Mar 01 Javascript
全面解析JS字符串和正则表达式中的match、replace、exec等函数
Jul 01 Javascript
Vue.js双向绑定实现原理详解
Dec 22 Javascript
bootstrap weebox 支持ajax的模态弹出框
Feb 23 Javascript
分享19个JavaScript 有用的简写写法
Jul 07 Javascript
react-router4 配合webpack require.ensure 实现异步加载的示例
Jan 18 Javascript
在vue中,v-for的索引index在html中的使用方法
Mar 06 Javascript
vue实现自定义日期组件功能的实例代码
Nov 06 Javascript
Angular 实现输入框中显示文章标签的实例代码
Nov 07 Javascript
微信小程序动态添加和删除组件的现实
Feb 28 Javascript
javascript 开发之网页兼容各种浏览器
Sep 28 #Javascript
JavaScript中重名的函数与对象示例详析
Sep 28 #Javascript
js 开发之autocomplete=&quot;off&quot;在chrom中失效的解决办法
Sep 28 #Javascript
微信小程序下拉刷新界面的实现
Sep 28 #Javascript
详解Vuex中mapState的具体用法
Sep 28 #Javascript
Node.js学习之地址解析模块URL的使用详解
Sep 28 #Javascript
javascript基于牛顿迭代法实现求浮点数的平方根【递归原理】
Sep 28 #Javascript
You might like
论坛头像随机变换代码
2006/10/09 PHP
第八节--访问方式
2006/11/16 PHP
一个比较简单的PHP 分页分组类
2009/12/10 PHP
几种有用的变型 PHP中循环语句的用法介绍
2012/01/30 PHP
CI框架中集成CKEditor编辑器的教程
2014/06/09 PHP
PHP 传输会话curl函数的实例详解
2017/09/12 PHP
PHP开发实现微信退款功能示例
2017/11/25 PHP
jquery控制listbox中项的移动并排序
2009/11/12 Javascript
window.event快达到全浏览器支持了,以后使用就方便了
2011/11/30 Javascript
关于jQuery新的事件绑定机制on()的使用技巧
2013/04/26 Javascript
js实现商城星星评分的效果
2015/12/29 Javascript
基于jquery实现图片上传本地预览功能
2016/01/08 Javascript
jQuery基于json与cookie实现购物车的方法
2016/04/15 Javascript
bootstrap vue.js实现tab效果
2017/02/07 Javascript
jQuery实现Table表格隔行变色及高亮显示当前选择行效果示例
2017/02/14 Javascript
详解vuelidate 对于vueJs2.0的验证解决方案
2017/03/09 Javascript
JQuery 获取多个select标签option的text内容(实例)
2017/09/07 jQuery
JavaScript实现淘宝京东6位数字支付密码效果
2018/08/18 Javascript
原生js实现公告滚动效果
2021/01/10 Javascript
浅谈React Native 传参的几种方式(小结)
2019/05/21 Javascript
jQuery创建折叠式菜单
2019/06/15 jQuery
Vue 通过公共字段,拼接两个对象数组的实例
2019/11/07 Javascript
[35:34]Liquid vs Winstrike 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
Django2.1.3 中间件使用详解
2018/11/26 Python
python实现感知机线性分类模型示例代码
2019/06/02 Python
python语言基本语句用法总结
2019/06/11 Python
Python根据指定文件生成XML的方法
2020/06/29 Python
scrapy redis配置文件setting参数详解
2020/11/18 Python
经典C++面试题一
2016/11/06 面试题
SQL面试题
2013/12/09 面试题
给儿子的表扬信
2014/01/15 职场文书
课前三分钟演讲稿
2014/04/24 职场文书
社区党员公开承诺书
2014/08/30 职场文书
经理岗位职责范本
2015/04/15 职场文书
Redis性能监控的实现
2021/07/09 Redis
vue3不同环境下实现配置代理
2022/05/25 Vue.js