基于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 相关文章推荐
js实现权限树的更新权限时的全选全消功能
Feb 17 Javascript
Jquery插件之多图片异步上传
Oct 20 Javascript
SeaJS入门教程系列之完整示例(三)
Mar 03 Javascript
jQuery+PHP实现动态数字展示特效
Mar 14 Javascript
如何使用jquery easyui创建标签组件
Nov 18 Javascript
JS实现简单易用的手机端浮动窗口显示效果
Sep 07 Javascript
vuejs动态组件给子组件传递数据的方法详解
Sep 09 Javascript
AngularJS实现在ng-Options加上index的解决方法
Nov 03 Javascript
微信小程序画布圆形进度条显示效果
Nov 17 Javascript
CKeditor富文本编辑器使用技巧之添加自定义插件的方法
Jun 14 Javascript
vue项目查看vue版本及cli版本的实现方式
Oct 24 Javascript
React实现todolist功能
Dec 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
关于php连接mssql:pdo odbc sql server
2011/07/20 PHP
通过PHP的内置函数,通过DES算法对数据加密和解密
2012/06/21 PHP
一个简单且很好用的php分页类
2013/10/26 PHP
PHP实现蛇形矩阵,回环矩阵及数字螺旋矩阵的方法分析
2017/05/29 PHP
Laravel 5.5 的自定义验证对象/类示例代码详解
2017/08/29 PHP
PHP实现模拟http请求的方法分析
2017/12/20 PHP
PHP仿tp实现mvc框架基本设计思路与实现方法分析
2018/05/23 PHP
PHP利用递归函数实现无限级分类的方法
2019/03/22 PHP
Yii框架核心组件类实例详解
2019/08/06 PHP
javascript 手动给表增加数据的小例子
2013/07/10 Javascript
javascript多物体运动实现方法分析
2016/01/08 Javascript
JavaScript获取客户端IP的方法(新方法)
2016/03/11 Javascript
jQuery实现鼠标跟随效果
2017/02/20 Javascript
EasyUI Datebox 日期验证之开始日期小于结束时间
2017/05/19 Javascript
用js屏蔽被http劫持的浮动广告实现方法
2017/08/10 Javascript
深入理解Vue官方文档梳理之全局API
2017/11/22 Javascript
基于Vue2.X的路由和钩子函数详解
2018/02/09 Javascript
jquery的 filter()方法使用教程
2018/03/22 jQuery
使用react render props实现倒计时的示例代码
2018/12/06 Javascript
Vue axios与Go Frame后端框架的Options请求跨域问题详解
2020/03/03 Javascript
Javascript执行上下文顺序的深入讲解
2020/11/04 Javascript
js实现扫雷源代码
2020/11/27 Javascript
Vue SPA 首屏优化方案
2021/02/26 Vue.js
一个检测OpenSSL心脏出血漏洞的Python脚本分享
2014/04/10 Python
12步教你理解Python装饰器
2016/02/25 Python
Python设计模式编程中Adapter适配器模式的使用实例
2016/03/02 Python
numpy添加新的维度:newaxis的方法
2018/08/02 Python
python 实现分页显示从es中获取的数据方法
2018/12/26 Python
计算机二级python学习教程(1) 教大家如何学习python
2019/05/16 Python
python基于paramiko将文件上传到服务器代码实现
2019/07/08 Python
对Pytorch中Tensor的各种池化操作解析
2020/01/03 Python
详解pandas apply 并行处理的几种方法
2021/02/24 Python
意大利香水和化妆品购物网站:Parfimo.it
2019/10/06 全球购物
师范毕业生自我鉴定
2014/01/15 职场文书
java设计模式--原型模式详解
2021/07/21 Java/Android
Node-Red实现MySQL数据库连接的方法
2021/08/07 MySQL