原生lay-search不支持拼音首字母匹配,必须修改notoption函数并预埋data-py属性;因其仅触发匹配判断,底层仍为indexof纯文本查找,不处理拼音转换。

原生 lay-search 不支持拼音首字母匹配,必须修改 notOption 函数的匹配逻辑,并为每个 option 预埋拼音首字母字段 —— 这是唯一稳定生效的路径。
为什么直接加 lay-search 没用
因为 lay-search 只是渲染一个输入框并触发 notOption 判断,底层仍是纯文本 indexOf 匹配。输入 “sh”,它不会查“上海”的拼音,只会找 DOM 文本里有没有连续的 “sh” 字符。常见现象包括:输 “zhang” 找不到 “张三”、输 “bj” 表格无反应、搜索后选项高亮错乱。
你看到的搜索效果,完全取决于 notOption 函数返回什么。不改它,加再多属性或监听 input 事件都没用。
必须改 form.js 中的 notOption 函数
定位到未压缩版 src/lay/modules/form.js(不是 layui.all.js),找到 notOption = function(value, callback, origin) 定义处。在原始判断行(如 not = text.indexOf(value) === -1)之前插入拼音预处理:
- 用
pinyin-pro(非pinyin-js)调用pinyin.getFirstLetter(text).toLowerCase()得到首字母,比如 “北京” →"bj" - 把原始判断改成:
!text.toLowerCase().includes(value) && !pinyinFirst.includes(value) -
value和拼音结果都转小写,避免大小写干扰 - 对空值、数字、英文混排项兜底,比如
""或"123"统一设为"#",防止getFirstLetter返回undefined
怎么给 option 预埋拼音首字母
不能靠每次搜索时实时计算拼音,数据量 >200 条就会明显卡顿。正确做法是在初始化前就为所有选项注入 data-py 属性:
<select lay-search><option value="1" data-py="bj">北京市</option> <option value="2" data-py="sh">上海市</option> <option value="3" data-py="gz">广州市</option></select>
生成方式示例(使用 pinyin-pro):
const options = document.querySelectorAll('select[lay-search] option');
options.forEach(opt => {
const py = pinyin.getFirstLetter(opt.textContent).toLowerCase() || '#';
opt.setAttribute('data-py', py);
});
注意:这个操作必须在 layui.form().render('select') 之前执行,否则 data-py 会被忽略。
表格 toolbar 搜索也得走同样逻辑
layui.table 的 search 配置(如 {id: 'searchBar'})只是个输入框 + reload(),过滤全靠 where 或 parseData。如果你用前端分页(page: false),就得自己写 filter 函数,且必须依赖预埋的拼音字段(如 pinyin_first),不能在回调里反复调用 pinyin.getFirstLetter()。服务端分页则需后端统一做拼音转换,比如 MySQL 用 CONVERT(name USING gbk) 配合正则。
最容易被忽略的是防抖:搜索框要加 setTimeout 缓冲(推荐 300ms),否则快速连按 “b”、“e”、“i” 会触发多次 reload,造成接口雪崩或 UI 跳动。











