根本原因是Layui表格翻页时重建DOM且未同步开关状态,必须在done回调中render switch并手动更新table.cache对应行数据,否则导出、排序等均使用旧值。
表格分页后Switch状态丢失的根本原因
不是switch组件坏了,是layui表格在翻页时重建了dom,但没同步你上一页操作过的开关状态——form.on('switch()')监听的是当前页的元素,新页的switch dom是全新渲染的,旧的事件绑定和数据映射全部失效。更关键的是:table.cache里那行数据的字段值(比如status)根本没被你手动更新过,所以翻页后它还是初始值。
必须在done回调里重新render switch并同步数据
光在页面初始化时调一次layui.form.render('switch')完全不够。表格翻页、重载、搜索后,新插入的input[lay-skin="switch"]元素不会自动绑定事件。
- 在
table.render()配置中必须写done: function(res, curr, count) { layui.form.render('switch'); } -
templet里的switch要带name和value,例如:<input type="checkbox" name="status_{{d.id}}" value="{{d.status ? 'on' : 'off'}}" lay-skin="switch"> -
form.on('switch(status_{{d.id}})')这种写法不行——filter不能动态拼接;正确做法是统一用一个lay-filter,比如lay-filter="statusSwitch",然后在回调里靠data.elem.closest('tr').dataset.index或d.id反查数据行
切换后必须手动更新table.cache,否则导出/排序全错
很多人只写了监听,却忘了这一步:Layui表格不感知自定义控件变化,table.cache['yourTableId']里的数据不会自动更新。你不改它,分页再点回来、导出Excel、甚至调用table.getData()拿到的都是旧值。
- 在
form.on('switch(statusSwitch)')回调里,立刻定位并更新对应行数据:var index = data.elem.closest('tr').dataset.index; table.cache['testTable'][index].status = data.elem.checked; - 更健壮的做法是按业务主键查找:
var row = table.cache['testTable'].find(r => r.id == data.elem.name.replace('status_', '')); if(row) row.status = data.elem.checked; - 如果用了
where参数触发table.reload(),记得在reload的done里也做一次状态恢复(从localStorage或变量读已选id列表,再批量赋值item.status)
容易被忽略的细节:value属性必须显式写死
data.value不是实时反映开关状态的,它只取自input的value属性初始值。如果你的templet里只写了<input name="status" ...>没写value,那无论怎么切,data.value永远是"on"。
- 务必在
templet中把value和数据字段绑定:value="{{d.status ? 'on' : 'off'}}" - 后端返回的数据字段(如
status: true)要和前端判断逻辑一致,避免true被当成undefined导致value为空 - 不要依赖
$('input').val()或.prop('checked')取值——它们在Layui switch上不可靠
table.cache,它一直拿着最初接口返回的值在渲染。真正的状态同步,从来不在DOM里,而在你主动维护的那一行table.cache[...].xxx = ...里。


















