layui select 分组必须手写 html 的 结构,不支持 js 数据自动渲染;动态更新需手动拼接含 的完整 html 并调用 form.render('select', 'filter')。

layui select 怎么用 <optgroup></optgroup> 实现分组
直接支持,但必须手写 HTML 结构,不能靠 layui.form.render() 自动解析 JS 数据生成分组。Layui 的 select 只渲染你给它的原始 DOM,它不帮你拼 <optgroup></optgroup> 标签。
常见错误是写了一堆 data-url 或用 layui.form.select('xxx', { data: [...] }) 想动态生成分组——这行不通,Layui 2.x 官方 API 里压根没提供分组数据格式支持。
- 必须在 HTML 里提前写好带
<optgroup label="xxx"></optgroup>的结构 - label 值会原样显示为分组标题,不支持模板或变量插值
- 每个
<optgroup></optgroup>下的<option></option>仍需有value和文本内容 - 如果后续要动态加载选项(比如 AJAX 拉取),得手动拼 DOM 字符串再
innerHTML替换,并重新调用form.render('select')
<select name="city" lay-filter="city"><optgroup label="华北地区"> <option value="bj">北京</option> <option value="tj">天津</option> </optgroup> <optgroup label="华东地区"> <option value="sh">上海</option> <option value="hz">杭州</option> </optgroup></select>
为什么 form.render('select') 不生效或分组消失
本质是 DOM 被重写了。典型场景:你先初始化了 select,后来又用 JS 清空并重新 append() 了一堆 <option></option>,但没保留原有的 <optgroup></optgroup> 结构,或者用了 innerHTML 直接覆盖,把整个 select 内容全刷掉了。
- Layui 渲染 select 依赖原始 DOM 层级,一旦
<optgroup></optgroup>被删掉,就再也找不回来 - 用
$('#xxx').html('...')或element.innerHTML = '...'时,务必确保新字符串里包含完整、嵌套正确的<optgroup></optgroup> - 如果用 jQuery 的
.empty().append(...),记得 append 的是含<optgroup></optgroup>的整段 HTML,不是只 append<option></option> - 渲染后若下拉框样式错乱,大概率是
form.render('select')调用时机不对——必须等 DOM 插入完成后再调
动态加载分组数据的最小可行做法
没有封装好的方法,只能手动拼。假设你从接口拿到的数据是按 group 分好组的对象数组:
[{group: "华北", options: [{value:"bj", title:"北京"}, {value:"tj", title:"天津"}]}, ...]
那就得自己转成 HTML 字符串再塞进去:
- 遍历 group 数组,每组拼一个
<optgroup label="xxx">...</optgroup> - 每个 group 内部再遍历
options,拼<option value="xxx">yyy</option> - 最后用
selectEl.innerHTML = htmlStr替换全部内容 - 紧接着调用
form.render('select', 'your-filter'),第二个参数是 form 容器的 lay-filter 值(不是 select 的)
注意:form.render() 第二个参数漏写或写错,会导致 select 看似没变化——它其实没找到所属的 form 容器,也就不会重新绑定事件和样式。
兼容性和视觉细节容易被忽略的地方
Layui 默认对 <optgroup></optgroup> 的 label 文字加了灰色样式,但这个颜色在深色主题或自定义 CSS 下可能看不清;而且所有浏览器对 <optgroup></optgroup> 的支持一致,但 Layui 的下拉面板是浮层模拟的,实际点击区域不包含 group 标题——也就是说,用户点“华北地区”那行是没反应的,这是预期行为,不是 bug。
- 不要给
<optgroup></optgroup>加disabled,Layui 不识别,且原生语义也不允许 - 移动端 Safari 下,
<optgroup></optgroup>标题可能比选项文字略小,若需统一字号,得额外加 CSS:select optgroup { font-size: inherit; } - 如果页面有多个 form,且都用了相同 lay-filter,
form.render('select', 'xxx')会批量处理所有匹配的 select,小心误操作
分组这事,核心就一条:Layui 不生成结构,只美化已有结构。你给它什么 DOM,它就渲染什么,多一重嵌套、少一个标签,结果都可能不对。










