如何实现动态内容条件筛选

简介: 这两天看了一下后端给的接口文档,每一个都要求筛选,而且这个筛选还是多条件的,还是不能固定的,要求根据用户的输入然后筛选,我之前的实现大概是这样子,当用户想要筛选的时候就去检索条件,并输入相关的内容进行筛选

这两天看了一下后端给的接口文档,每一个都要求筛选,而且这个筛选还是多条件的,还是不能固定的,要求根据用户的输入然后筛选,我之前的实现大概是这样子,当用户想要筛选的时候就去检索条件,并输入相关的内容进行筛选

13.png

所以这种策略的话,就是需要实现以下两个核心点

  1. 监听输入
  2. 筛选数据

接下来就会针对这两点进行一个分析

监听输入

因为是动态内容,因此需要监听输入框的数值改变,当用户的输入停止时或者说失去了焦点,这个时候进行一个筛选,那么监听输入这个就有点来头了,虽然我用的是 vue, vue 有着响应式数据的加持,但是这个用响应式不太行,为什么呢?因为我这个的设计上是没有一个确定键的,不像百度,输入完搜索字符串然后就可以回车或者点搜索按钮,但我这个就有点讲究,这是一个实时响应的搜索,到这里又有点像百度,因为我们在百度搜索的时候输入部分关键字,可能你需要的结果就已经出现了,比如下面这样

14.png

本来想搜掘金的,只打了个怎么就有提示信息了呢?是因为我们输入的时候就已经发送请求到服务端了,服务端返回了结果并渲染,但是百度是这方面的专家,它返回检索信息的速度快到让人以为它其实监听的 <input> 是输一个字符就发一次请求,像普通人的服务器还是要做一下优化的,不然搜的太快,内容不是用户想要的,浪费了性能,增加了服务器压力,看到这里你可能已经懂了,优化方案就监听输入方面要讲的主角,防抖和节流

防抖节流两兄弟多少都听过一些,最简单的介绍就是

  1. 间隔时间内只执行一次
  2. 间隔时间内执行

防抖/节流

那么防抖用在输入框这个场景适不适合呢?虽然防抖节流定义是这么说,但是面对不同的场景,还是需要不同的拟像化描述一下这个场景,想象一下

  1. 面对狂风骤雨般的输入,等到用户累了,不想输入后达到 1s 再发送请求合适吗?
  2. 面对狂风骤雨般的输入,每到 1s 后就发送一次请求合适吗?

这时候就要思考你要面对用户的场景了,是满足用户好奇宝宝的心态,设置一个比较小的阈(yu)值呢?还是培养用户的耐心,就得等你停止输入才能给你答案

加锁

讲了这么多,你可能在想我最后选用了什么?其实我是监听了 <el-input> 的 change 事件

img

为什么说它是加锁呢?因为这个 change 事件是只有你 input 失去焦点或者按下回车后才会触发,相当于只有失去焦点按下回车这两把钥匙之一才能够打开 change 这个锁,像一些按钮面对短时间内大量的点击事件也未必要上防抖节流,简单的等待后端返回响应后再解锁然后恢复点击状态

筛选数据

面对多个条件的后端接口,在前端可以一次性请求回来并进行筛选,然后得到最终的数据,其实有一个就是可以基本无视筛选算法好坏的解决方案

HTML5 Web Workers

这个其实有点 Android 内味了, Android 其实是不能在渲染线程中操作数据的,得另开一个线程,类比到 web 页面这里,大量的 JS 计算会阻塞页面的渲染和交互,如果有个另一个线程给我跑筛选不就行了, Web Workers 就是干这事的,甭管什么 O(nlogn), O(n^2), O(n), 怎么整都不会影响你的页面

善用 JS API

让我们看看普通人写筛选是怎么样的,每次筛出一部分然后继续拿筛好的和剩下的继续筛,无脑套好几个 for 循环

// filter
const filterChange = async () => {
  let nameFilterList: People[] = [];
  let idFilterList: People[] = [];
  let res: People[] = [];
  // 获取数据
  const allFilterlist = [nameFilterList, idFilterList];
  for (let i = 0; i < allFilterlist.length; i++) {
    if (allFilterlist[i].length > 0 && res.length > 0) {
      allFilterlist[i].forEach((i) => {
        const temp: People[] = [];
        res.forEach((j) => {
          if (i.number === j.number) {
            temp.push(j);
          }
        });
        res = temp;
      });
    } else if (allFilterlist[i].length > 0 && res.length === 0) {
      res.push(...allFilterlist[i]);
    }
  }
  list.value = res;
};

其实完全可以 JS 新增的 Set API 来解决这个问题,筛选,本质上就是求交集,求交集用 Hash 的思想就能够做到 O(n+m) 的时间复杂度, 先遍历一遍筛选条件1对应数组, 将唯一值,因为我们数组元素往往都是一个复杂的对象,可以将对象中的唯一值抽出来做 Hash 达到减少空间复杂度的目的, 比如 ID,代码如下

const allFilterlist = [nameFilterList, idFilterList];
for (let i = 0; i < allFilterlist.length; i++) {
  if (allFilterlist[i].length > 0 && res.length > 0) {
    res = intersect(allFilterlist[i], res);
  } else if (allFilterlist[i].length > 0 && res.length === 0) {
    allFilterlist[i].forEach((item) => set.add(item.name));
    res.push(...allFilterlist[i]);
  }
}
const intersect = (arr1: People[], arr2: People[]): People[] => {
  const set = new Set();
  const res: People[] = [];
  arr1.forEach((item) => set.add(item.name));
  arr2.forEach((item) => {
    if (set.has(item.name)) {
      res.push(item);
    }
  });
  return res;
};

时间复杂度将由原来的 O(n*m*p) 变为 O(n*(m+p)),算是减少了一个量级

总结

筛选这块遇到的难点,其实就是筛选数据优化这块,其实这种东西能用就行,但还是可能出于自己的盲目自信,老是想着优化,然后就把大把的时间给浪费了

相关文章
分页最好的作用是做好统计,可以用来基本条件列表的统计,可以用来统计多平台,使之呈现列表,预算统计,以及必要的技术,项目名称,常用链接
分页最好的作用是做好统计,可以用来基本条件列表的统计,可以用来统计多平台,使之呈现列表,预算统计,以及必要的技术,项目名称,常用链接
|
5月前
|
SQL Java 数据库连接
大事件后端项目28------文章分类列表查询(条件分页)
大事件后端项目28------文章分类列表查询(条件分页)
|
5月前
|
SQL 数据库 UED
条件筛选大作战:解析Where与Having的区别与应用
条件筛选大作战:解析Where与Having的区别与应用
43 0
|
6月前
|
供应链 搜索推荐
偏好类标签支持自定义统计方式,标签场景覆盖更广
在个性化营销场景,零售商必须理解顾客的行为才能更准确的预测客户需求,优化库存管理、制定营销策略,并提供个性化的购物体验,然而偏好类标签的加工不仅仅是简单的属性出现频次或最大值的统计,Dataphin V4.0版本新增了自定义统计的方式加工偏好标签,通过简单的配置即可完成复杂的标签加工场景。
|
PHP
php清洗数据实战案例(4):按照关联数组相同值名称进行筛选后对不同的指标予以合并计算的解决方案
php清洗数据实战案例(4):按照关联数组相同值名称进行筛选后对不同的指标予以合并计算的解决方案
65 0
|
SQL JavaScript 关系型数据库
API接口获得数据后处理JS数组(包含字符串对象)分组、过滤和筛选的解决方案
API接口获得数据后处理JS数组(包含字符串对象)分组、过滤和筛选的解决方案
161 0
|
存储 开发框架 前端开发
ModStartCMS v5.5.0 页面标签支持,用户逻辑优化
ModStart 是一个基于 Laravel 模块化极速开发框架。模块市场拥有丰富的功能应用,支持后台一键快速安装,让开发者能快的实现业务功能开发。
“关联表单”组件文本数据筛选只支持包含条件的解决方案
在“关联表单”中使用数据筛选功能筛选文本时条件只有”包含“,此文章通过增加一个”下拉单选“组件,变相解决这个问题。
198 0
流程定义查询和删除
流程定义查询流程定义查询和删除
|
SQL 关系型数据库 MySQL
新增数据添加IF逻辑判断操作
新增数据添加IF逻辑判断操作
193 0