layui 的 lay-skin="switch" 仅支持 checkbox,不支持 radio;需用两个同名 radio 配合 css 伪装开关,并确保 name/value 正确、隐藏原生元素、监听 change 事件、正确调用 form.render()。

为什么不能直接用 lay-skin="switch" 给 radio
因为 layui 的 lay-skin="switch" 只对 type="checkbox" 生效,对 type="radio" 完全无效——源码里压根没处理 radio 的 switch 渲染逻辑。你加了也白加,浏览器还是显示小圆点。
想实现“开关样式 + 单选行为”,必须绕开这个限制:用两个同名 radio(比如 name="status"、value="true" 和 value="false"),再用 CSS 把它们伪装成一个滑动开关。
怎么用 radio 模拟开关并保持表单同步
核心是保留原生语义,不破坏 form.val()、校验、重置等内置行为。只要 name 和 value 正确,layui 就能识别。
- HTML 结构必须包含两个同名
input[type="radio"],其中一个带checked属性(默认状态) - 用
display: none隐藏原生 radio,避免样式冲突 - 用伪元素或外层容器画轨道和滑块,根据
e.target.value切换 active 状态 - 监听原生
change事件,不要用form.on('radio(filter)')—— 后者只是代理,且可能干扰初始状态
示例片段:
<div class="layui-form-item">
<label class="layui-form-label">启用通知</label>
<div class="layui-input-block">
<input type="radio" name="notify" value="true" title="开" checked><input type="radio" name="notify" value="false" title="关">
</div>
</div>
form.render() 时机不对会导致样式失效
常见错误是 DOM 插入完才调 form.render(),结果 layui 自动给 radio 套上默认 UI(比如加个 label 包裹、渲染成文字+圆点),你的自定义 CSS 就被覆盖了。
- 必须在
form.render('radio')或form.render()之前完成 DOM 插入和初始样式设置 - 如果表单是动态加载的(比如 ajax 加载后插入),要显式调用
form.render('radio', 'your-filter'),第二个参数填你表单的lay-filter值,否则只传'radio'会作用于全局所有 radio - 别依赖
form.on('radio()')来初始化状态——它只响应后续点击,不负责初始渲染
表格里用 radio 实现单选开关更简单
如果是在 table.render() 里,直接配列项 {type: 'radio', fixed: 'left'},不用写 HTML、不用写 CSS、不用监听事件。
- 确保每行数据有唯一
value(比如d.id),name 统一(如name="selectedId") - 默认选中靠数据字段驱动:返回的数据里带
checked: true字段即可 - 获取选中行用
table.on('radio(filter)', ...)回调里的obj.data,别用checkStatus().data[0]—— 那个方法在事件触发前可能还没更新
表格场景下,这比手写开关更轻量、更稳定,也更容易和后端数据对齐。
真正容易被忽略的是:开关的视觉反馈和表单值必须严格一致。哪怕 CSS 滑块动了,如果 underlying radio 没真正切换,form.val() 就拿不到正确值——所以永远优先信任原生控件状态,而不是视觉表现。











