Layui transfer 组件无内置最大选中数限制,需手动监听DOM点击拦截、单独处理全选按钮,并在render done回调中持久化选中状态,否则reload后状态丢失。
layui transfer 组件没有内置最大选中数限制
layui 的 transfer 组件本身不提供 maxchecked 或类似配置项,左侧列表(data 源数据)的勾选行为完全由 form 模块接管,而 form 对 checkbox 的统一监听无法区分 transfer 内部的复选框。直接套用 form.on('checkbox') 会误伤其他表单控件,且无法精准定位到 transfer 的左侧项。
必须监听 transfer 渲染后的 DOM 并手动拦截点击
transfer 渲染后,左侧列表每一项的复选框结构固定:<input type="checkbox" name="transfer[0]">(name 值含索引)。需在 transfer.render() 完成后,用事件委托监听其左侧容器(class 为 layui-transfer-box layui-transfer-box1)内的点击:
- 先统计当前已勾选的左侧项数量:
$('input[name^="transfer["][type="checkbox"]:checked').length - 若已达上限(如 3),且用户点击的是未勾选的 checkbox,则调用
event.preventDefault()阻止默认行为 - 立即更新 checkbox 状态(设为
checked = false),再调用form.render('checkbox')同步 UI - 注意:不能只靠
return false,Layui 的 checkbox 渲染依赖form.render(),否则界面与状态不同步
左侧全选按钮需单独处理
transfer 的左侧“全选”按钮(class layui-transfer-header 下的 checkbox)触发时,name 为 transferAll1。它不走普通 checkbox 监听逻辑,必须额外绑定:
- 监听
click事件而非form.on,目标是.layui-transfer-box1 .layui-transfer-header input[type="checkbox"] - 获取当前左侧所有可选项数量:
$('.layui-transfer-box1 .layui-transfer-body li').length - 计算剩余可勾选数:
MAX_SELECT - 已勾选数;若 ≤ 0,直接取消全选状态并提示 - 若 > 0,只勾选前
剩余数个未勾选项(用:not(:checked):lt(N)选取),再form.render('checkbox')
跨页或动态刷新时状态易丢失
transfer 不维护内部选中状态,每次 transfer.render() 或 transfer.reload() 都会重绘 DOM,导致手动设置的勾选状态清空。解决办法只有两个:
- 把已选 ID 存在外部变量(如
window.transferSelected = []),并在每次 render 的done回调里遍历 data,对匹配项手动设checked = true,再form.render('checkbox') - 避免 reload,改用 JS 动态增删
data数组后调用transfer.set({data: newData})(Layui 2.8+ 支持),该方法保留已有勾选状态 - 切勿在
done里直接操作input.checked后不调form.render(),否则 checkbox 图标不会变
实际限制逻辑最脆弱的一环不是点击拦截,而是状态持久化——只要 reload 或重新 render,没做显式恢复,之前选中的就没了。这个细节多数人第一次写就会漏。


















