小数据量(≤1000行)宜前端JS实时过滤,遍历tbody行并用统一布尔表达式匹配非空条件;大数据须后端分页查询,前端通过原生form+FormData传参,name属性须与API参数严格一致。

小数据量(≤1000 行)直接用 JS 前端过滤最简单;真实业务中数据来自后端、需分页或权限控制,必须走后端查询——前端只负责收参数、发请求、渲染结果。
前端实时过滤:用 filterTable() 一次性比对所有非空条件
别写多个 .filter() 链式调用,也别嵌套 if 判断。每行是否显示,由一个统一布尔表达式决定:
-
const nameMatch = !nameVal || cellName.includes(nameVal)—— 空输入视为“不限制” -
const deptMatch = !deptVal || cellDept === deptVal—— 精确匹配优先用data-dept属性值,而非单元格文本 - 最终判断:
row.style.display = nameMatch && deptMatch ? '' : 'none' - 监听所有输入框共用同一个回调,避免竞态:改两个框时,只触发一次完整过滤
后端驱动筛选:用 <form></form> + FormData 安全传参
不用 <div class="filter-form">,必须用原生 <code><form></form> 标签包裹所有筛选控件:
-
name属性必须和后端 API 的 query 参数名完全一致,比如price_min、status - 多选 checkbox 写成多个同名
<input name="tag" value="vue">,不是name="tag[]"(后者在纯 JS 场景下无效) - 提交前用
new FormData(form)读取,再转对象:Object.fromEntries(formData.entries()) - 空值自动被忽略,disabled 控件不参与提交,checkbox 未勾选也不上传——不用手动清理
防坑重点:DOM 遍历范围、文本清洗、display 还原
前端过滤时最容易出错的三个点:
立即学习“前端免费学习笔记(深入)”;
- 只遍历
tbody tr,别用table tr,否则可能误操作表头或脚部行 - 单元格文本要清洗再比对:
cell.textContent?.trim().replace(/[\s\uFEFF\xA0]+/g, ' '),否则全角空格、换行、多余空格会导致===失败 -
tr.style.display = ''不一定还原原始值(比如原来是flex),稳妥做法是提前存tr.dataset.originalDisplay,或统一用classList.toggle('hidden')
复杂点不在逻辑本身,而在于边界处理:空输入怎么算、多空格怎么归一、表格结构变动后 JS 是否还能准确定位列、用户快速连输时防抖要不要加——这些细节漏掉一个,筛选就不可靠。



















