小数据量前端过滤最省事,但分页、权限、数据库查询必须后端处理;多条件“与”逻辑应单次遍历+组合布尔表达式,用&&连接并默认true;须用获取控件值;所有筛选框共用防抖回调;大数据量需虚拟滚动或显隐控制。

小数据量(≤1000 行)直接用 JavaScript 前端过滤最省事;真实业务中只要涉及分页、权限或数据库查询,就必须交由后端处理——前端只负责收条件、发请求、渲染结果。
怎么用 JS 实现多条件“与”逻辑过滤(非链式 filter)
链式调用 .filter().filter() 会反复创建新数组,中间某次筛空后,后续条件就无从判断;嵌套 if 又容易漏掉“全部满足”的语义。正确做法是单次遍历 + 组合布尔表达式:
- 每个条件默认返回
true(即不参与限制),避免空输入导致整行被隐藏 - 用
&&连接所有条件,如:(!nameVal || row.name.includes(nameVal)) && (!deptVal || row.dept === deptVal) - 数值字段要先转字符串再比对:
row.salary.toString().includes(salaryKeyword),否则100000.includes("10")会报错 - 空值(
null/undefined)提前跳过,别让.toLowerCase()崩溃
为什么必须用 而不是 包裹筛选项不用 的后果很直接:你得手动遍历每个 、判断 type、处理多选、拼 query string——DOM 结构一变,JS 就断。而 天然支持:
-
form.elements 直接拿到所有控件,包括 和未选中的 checkbox
-
new FormData(form) 自动忽略 disabled 项、合并同名 name(如多个 brand)、跳过未选中的 checkbox
-
name 必须和后端 API 参数名完全一致,比如后端接收 ?status=active&category=tech,那前端就得写 和
- 别写
name="brand[]"——这是 PHP 风格,FormData 不识别方括号,后端根本收不到
input 事件监听多个框,怎么避免竞态和状态错乱
每个输入框单独绑 input 没问题,但回调里不能各自执行一次完整过滤。用户同时改两个框,后触发的那个会覆盖前一个的结果,造成“只响应最后一次输入”的假象。
- 所有筛选框共用一个统一回调,比如
onFilterChange()
- 回调内一次性读取全部值:
const name = nameInput.value.trim(); const dept = deptInput.value;
- 加防抖(
setTimeout + clearTimeout),延迟 200–300ms,避免每打一个字就重绘 DOM
- 空值检查必须放在过滤前:
if (!name && !dept) return;,否则 trim() 后为空字符串仍会触发无效过滤
大数据量下怎么避免卡顿和误操作
几千行表格 + 每次 innerHTML 替换整个 ,滚动和输入都会明显掉帧。显隐控制比删增节点快得多,但前提是数据源在 JS 中而非靠遍历 DOM 提取:
- 原始数据必须存在 JS 数组里(如
tableData = [{name: "张三", dept: "前端"}]),别现场读 row.cells[0].textContent
- 过滤逻辑只跑这个数组,渲染用模板字符串一次性写入
,或用 documentFragment 批量插入
- 容器设固定高度 +
overflow-y: auto,配合 tr.style.display = 'none' 控制显隐,别反复 removeChild
- 上万条数据就别硬筛了——改用虚拟滚动,只渲染可视区域的
- 导出按钮的数据源、总条数显示、分页器总数,必须基于当前筛选结果,而不是原始
tableData.length
最容易被忽略的是:所有筛选条件的“空值语义”必须统一——不是“不填”,而是“不限制”。一旦某个字段的空值被当成 false 条件参与 && 判断,整行就没了。这点在联动筛选和后端参数透传时尤其关键。
不用 的后果很直接:你得手动遍历每个 、判断 type、处理多选、拼 query string——DOM 结构一变,JS 就断。而 天然支持:
-
form.elements直接拿到所有控件,包括和未选中的checkbox -
new FormData(form)自动忽略 disabled 项、合并同名name(如多个brand)、跳过未选中的 checkbox -
name必须和后端 API 参数名完全一致,比如后端接收?status=active&category=tech,那前端就得写和 - 别写
name="brand[]"——这是 PHP 风格,FormData不识别方括号,后端根本收不到
input 事件监听多个框,怎么避免竞态和状态错乱
每个输入框单独绑 input 没问题,但回调里不能各自执行一次完整过滤。用户同时改两个框,后触发的那个会覆盖前一个的结果,造成“只响应最后一次输入”的假象。
- 所有筛选框共用一个统一回调,比如
onFilterChange() - 回调内一次性读取全部值:
const name = nameInput.value.trim(); const dept = deptInput.value; - 加防抖(
setTimeout+clearTimeout),延迟 200–300ms,避免每打一个字就重绘 DOM - 空值检查必须放在过滤前:
if (!name && !dept) return;,否则trim()后为空字符串仍会触发无效过滤
大数据量下怎么避免卡顿和误操作
几千行表格 + 每次 最容易被忽略的是:所有筛选条件的“空值语义”必须统一——不是“不填”,而是“不限制”。一旦某个字段的空值被当成 false 条件参与 innerHTML 替换整个 ,滚动和输入都会明显掉帧。显隐控制比删增节点快得多,但前提是数据源在 JS 中而非靠遍历 DOM 提取:
tableData = [{name: "张三", dept: "前端"}]),别现场读 row.cells[0].textContent
,或用
documentFragment 批量插入
overflow-y: auto,配合 tr.style.display = 'none' 控制显隐,别反复 removeChild
tableData.length
&& 判断,整行就没了。这点在联动筛选和后端参数透传时尤其关键。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











