layui 中无法用 radio 实现三级联动,必须使用 select 配合 form.on('select(xxx)');需按唯一 lay-filter 绑定事件,动态清空并追加 option 后调用 form.render('select'),注意 pid 字符串匹配、disabled 控制及表格内应通过弹窗闭环处理。

layui 里没有“单选框三级联动”这种东西——radio 本身不支持动态选项更新,也不响应 change 事件链式驱动下级。你要的其实是「用 select 实现三级联动」,但误用了“单选框”这个词。
为什么不能用 radio 做三级联动
根本原因是:radio 是静态控件,Layui 的 form.render('radio') 只重绘 UI 样式,不重建选项结构;你没法在 JS 里动态增删 input[type=radio] 并保持校验、禁用、选中状态同步。所有所谓“radio 联动”的实现,底层都是伪装成 radio 样式的 select 或自定义弹窗。
form.on('select(xxx)') 是唯一可靠入口
Layui 的联动必须基于 select + form.on('select(xxx)'),这是框架唯一暴露的、带上下文(data.value、data.elem)的联动钩子。别试图监听 radio 的 click 或用 $().on('change') 绑定原生事件——Layui 表单模块会覆盖这些行为,导致状态不同步。
- 每个
select必须有唯一lay-filter,比如lay-filter="province" - 回调里拿到
data.value后,立刻清空下级select的innerHTML,再 append 新option - 追加完必须调用
form.render('select'),否则 UI 不变;如果只渲染某一个,用form.render('select', 'your-form-class') - 别忘了手动设置下级
select的disabled状态:未选上级时禁用,选了才启用
后端数据结构必须是平铺 + pid
前端过滤依赖字符串精确匹配,后端返回的数据要是扁平数组,每项带 id 和 pid 字段,且类型一致:
[
{"id": "110000", "name": "北京市", "pid": "0"},
{"id": "110100", "name": "市辖区", "pid": "110000"},
{"id": "110101", "name": "东城区", "pid": "110100"}
]
- 前端用
data.filter(item => item.pid === selectedId)过滤,注意===左右都是字符串 - 别传数字过去,比如
item.pid === 110000永远 false - 清空下级时,要同时清 DOM、清
value、重置disabled、触发form.validate()清错误提示
表格内联动必须用弹窗闭环处理
在 layui.table 的单元格里硬塞 select 是自找麻烦:分页、排序、reload 会让事件丢失,联动中断。正确做法是:
- 列设为文本显示,加
lay-event="edit" - 点击触发
layer.open弹窗,里面放完整三级select - 弹窗内做全部联动逻辑,提交后调用
table.updateCell('id', rowIndex, 'district', newValue)更新视图 - 别用
table.reload()全量刷新,它会丢掉当前编辑态和滚动位置
真正卡住人的从来不是怎么拼 option,而是 form.render('select') 漏了、value 没清、pid 类型错、或者在表格里直接操作 DOM —— 这四点漏一个,联动就断在用户手里。











