远程搜索必须关闭原生lay-search,改用自定义输入框+防抖请求;formSelects需正确配置URL、keyword字段及数据格式;高亮需手动patch notOption后处理DOM;xm-select虽开箱即用但格式敏感。
远程搜索必须关掉原生 lay-search
原生 lay-search 只做前端过滤,和远程请求完全冲突。一旦同时启用,会出现「输完词没反应」或「结果忽有忽无」——本质是本地过滤逻辑还在跑,但 dom 已被远程数据重写,两者打架。
正确做法是:移除 lay-search 属性,改用自定义输入框 + 手动触发远程请求。Layui 的 formSelects 或 xm-select 插件内部就是这么干的,但如果你用原生 select,就得自己搭骨架:
- 把
<select>包在<div class="layui-form-select">里(不渲染也行,只为结构一致) - 额外加一个
<input type="text" class="layui-input search-input">作为搜索入口 - 监听
input事件,用setTimeout做防抖(推荐 300ms),避免用户连打时疯狂刷接口 - 请求返回后,清空原有
<dd>,用$.each(data, ...)动态生成新<dd lay-value="xxx">xxx</dd>
formSelects 远程搜索怎么配 URL 和字段映射
formSelects 是目前最稳的远程方案,它自动处理防抖、loading 状态、空结果提示,但配置错一个字段就搜不出东西。
关键点在 data(id, 'server', { ... }) 的参数:
-
url必须是完整路径,比如'/api/depts?keyword=' + keyword,不能只写'/api/depts'(它不会自动拼参) -
keyword配置的是后端接收关键词的字段名,比如后端要的是q,你就得写{ keyword: 'q' } - 返回数据必须是数组,每项至少含
name和value字段;如果后端返回的是label/id,得提前用map转换:res.data.map(x => ({ name: x.label, value: x.id })) - 调用前确保已初始化:
formSelects.data('deptSelect', 'server', { ... })中的'deptSelect'必须和原始<select id="deptSelect">的id一致
高亮匹配字符需要自己 patch notOption 函数
Layui 搜索逻辑藏在 form.js 的 notOption 函数里,它决定每个 <dd> 显示还是隐藏。高亮不是内置功能,必须手动修改 DOM 文本节点。
思路是:在远程返回数据并插入 <dd> 后,遍历所有匹配项,把关键词替换成带 <span class="highlight"></span> 的 HTML:
function highlightText(text, keyword) {
if (!keyword) return text;
const reg = new RegExp(`(${keyword})`, 'gi');
return text.replace(reg, '<span class="highlight">$1</span>');
}
// 插入 dd 后执行
$('dd').each(function() {
const $dd = $(this);
const rawText = $dd.text();
$dd.html(highlightText(rawText, currentKeyword));
});
注意两点:
- CSS 得自己加:
.highlight { background: #ffd860; font-weight: bold; } - 别在
notOption内部改——那函数只管显隐,不负责渲染;高亮必须放在数据插入完成之后做
为什么不用 xm-select 直接开箱即用
xm-select 确实自带高亮,调用 highlight: true 就行,但它对数据格式更敏感,且依赖 preact 渲染层。
容易踩的坑:
- 远程返回数据若没按
{ label: 'xxx', value: 'yyy' }格式,得用props: { name: 'label', value: 'value' }显式声明,漏配就空白 - 高亮只作用于
label字段,如果你的搜索依据是另一个字段(比如后台用code模糊查,但只显示name),得在remoteMethod里手动合并字段再塞进label - 如果项目里已有大量
form.render('select')调用,xm-select不会响应这些,得全部换成xmSelect.render()初始化
真正麻烦的从来不是加高亮,而是确保关键词从输入框进、经网络传、在服务端被正确解析、再带着上下文返回、最后在前端不被转义地渲染出来——中间任何一环断了,高亮都只是个摆设。


















