layui select 分组必须手写 <optgroup> 标签,不支持 JS 数据自动渲染;form.render('select') 仅解析原始 DOM,需确保 <optgroup> 为 <select> 直接子元素、label 非空且 DOM 已挂载,动态数据须手动拼接 HTML 并调用 form.render()。

layui select 必须手写 <optgroup>,不支持 JS 数据自动渲染分组
layui 的 form.render('select') 只读取原始 DOM 结构,不会根据 JS 数组或配置项帮你生成 <optgroup> 标签。常见错误是写一堆 data: [{group: '前端'}, {value: 'vue'}] 然后调用 form.render(),结果分组完全不出现——因为 layui 压根不解析这类数据格式。
必须在 HTML 中提前写出完整、嵌套正确的结构:
<select name="tech" lay-filter="tech">
<option value="">请选择技术</option>
<optgroup label="前端框架">
<option value="vue">Vue.js</option>
<option value="react">React</option>
</optgroup>
<optgroup label="后端语言">
<option value="node">Node.js</option>
<option value="python">Python</option>
</optgroup>
</select>
-
label属性不可省略且不能为空,否则浏览器直接忽略该<optgroup> -
<optgroup>必须是<select>的**直接子元素**,嵌套在<div>或条件模板里会静默失效 - 渲染前确保 DOM 已插入页面,
form.render('select')才能生效
动态加载分组数据时,必须手动拼 HTML 字符串再替换
从接口拿到的分组数据通常是对象数组形式,比如:[{group: "华北", options: [{value:"bj", title:"北京"}]}, ...]。layui 没有内置方法转成 <optgroup>,只能自己拼:
const html = groups.map(g => `
<optgroup label="${g.group}">
${g.options.map(o => `<option value="${o.value}">${o.title}</option>`).join('')}
</optgroup>
`).join('');
document.getElementById('mySelect').innerHTML = html;
form.render('select', 'myFilter');
- 用
innerHTML = html替换整个内容,不要只append()<option>——否则<optgroup>会被丢掉 - 若用 jQuery,避免
.empty().append('<option>...'),改用.html(html) - 拼接时注意 XSS 风险,对
g.group和o.title做基础 HTML 转义(如replace(/&/g, '&'))
旧版 layui(2.7 及以下)不支持 form.select(),别踩 form.select is not a function 的坑
layui 2.8 才新增 form.select({ elem: '#xxx', data: [...] }) 方法,它内部会尝试模拟分组,但本质仍是手动插入禁用占位项 + CSS 样式 + JS 禁用点击。2.7 及更早版本调用会直接报错。
- 确认版本:查看引入的
layui.js文件头注释,或运行layui.version - 若无法升级,老办法只有两种:
<optgroup>手写静态结构,或用formSelects插件替代(需额外引入) - 强行在 2.7 调用
form.select()不仅报错,还可能污染 form 模块状态
<optgroup disabled> 不隐藏标题,这是规范行为不是 bug
给 <optgroup> 加 disabled,只是让内部所有 <option> 变灰不可选,label 文字依然显示。很多人误以为“标题还在=没禁用”,其实已生效。
- 想彻底隐藏某组?只能用 JS 移除对应
<optgroup>节点,或服务端不输出 - 禁用单个选项,直接加
<option disabled>即可,不用动<optgroup> -
<optgroup>本身没有value,设了也无效;表单提交只取<option>的value


















