layui本身不提供局部搜索内置方法,需手动用filter过滤originaldata再table.render重绘当前页,关键设page:false且存原始数据于done回调。

layui table 怎么实现局部搜索(不重载整个表格)
直接说结论:layui 本身不提供「局部搜索」的内置方法,但可以通过 filter + data + render 组合手动实现——关键不是调接口,而是操作已加载的数据缓存。
为什么不能用 reload 或 reloadData
很多人一上来就查 table.reload,结果发现它默认会发请求、清空当前数据、重新渲染——这不是局部搜索,是整表刷新。真正要局部搜索,必须绕过请求,只对已有的 table.cache['yourId'] 做过滤。
-
table.reload默认触发url请求,即使传了data也会被忽略(除非显式设page: false且不带url) -
table.reloadData是 layui 2.8+ 新增方法,但它仍要求传入完整数据数组,且不保留原分页状态,容易导致页码错乱 - 真正可控的方式:自己维护一份原始数据副本,每次输入时用
filter筛出匹配项,再用table.render重绘当前页内容(注意:只 render 当前页,不是全量)
怎么写一个可运行的局部搜索逻辑
核心三步:存原始数据 → 监听输入 → 过滤并重绘当前页。假设你表格的 id 是 userTable,搜索框 input 的 id 是 searchInput:
let originalData = []; // 全局存原始数据
// 初始化表格时,把 data 存下来
table.render({
elem: '#userTable',
url: '/api/users',
cols: [[{field:'username', title:'用户名'}]],
done: function(res, curr, count) {
originalData = res.data || []; // 注意:这里存的是接口返回的 data,不是 table.cache
}
});
// 搜索监听(防抖建议加上)
$('#searchInput').on('input', function() {
let keyword = this.value.trim();
if (!keyword) {
table.render({
elem: '#userTable',
data: originalData,
cols: [[{field:'username', title:'用户名'}]],
page: false // 关键:禁用分页,否则 render 会强制走分页逻辑
});
return;
}
let filtered = originalData.filter(item =>
item.username && item.username.includes(keyword)
);
table.render({
elem: '#userTable',
data: filtered,
cols: [[{field:'username', title:'用户名'}]],
page: false
});
});
注意:page: false 必须显式设置,否则 table.render 会按默认分页规则切数据,导致只显示第一页的 10 条,哪怕你 filtered 出来 50 条。
容易漏掉的坑和兼容点
局部搜索看着简单,实际几个细节不处理就会失效:
- 原始数据必须在
done回调里取res.data,别用table.cache['userTable']—— 它只存当前页数据,翻页后就变了 - 如果表格启用了
toolbar或totalRow,render后它们不会自动更新,得手动调table.setTotalRow或重绘 toolbar 区域 - 搜索后点击排序或列筛选,会丢失过滤状态——因为这些操作底层也依赖
table.cache,你需要把 filtered 数据也同步进 cache(用table.cache['userTable'] = filtered),但要注意这会影响后续 reload 行为 - IE 下
Array.prototype.includes不支持,得换成indexOf !== -1或加 polyfill
最麻烦的其实是「恢复全部数据」的按钮逻辑——很多人只写了搜索,忘了点清空时要还原到原始数据+原始分页状态,而不仅仅是重新 render。











