失焦时Ajax校验必须用form.on('change')而非原生blur,因Layui校验依赖内部事件通道;自定义规则需同步return错误字符串才能触发红边框与提示,且手动改值后须调form.validate()确保数据同步。

失焦时发起 Ajax 校验必须用 form.on('change'),不能用原生 blur
直接给 input 绑 blur 并调 form.validate() 会失败:Layui 的验证状态、form.val()、红边框(lay-form-danger)都依赖内部事件通道,原生事件绕过它,校验结果不更新、提示不显示、缓存值也不变。
正确入口是 form.on('change', 'input[name][lay-verify]', fn)——它在「值变化 + 失焦」后触发,与 Layui 校验链路完全对齐,且能保证 data.elem.value 是最新值。
- 必须确保
input有name属性,否则form.on('change')不识别 - 动态添加的
input要先执行form.render('input'),否则事件不绑定 - 回调中用
data.elem拿 DOM 元素,别用this(闭包里容易指向错)
form.verify() 里写 Ajax 必须 async: false,且错误信息要 return 出来
Layui 验证钩子不支持 Promise 或 async/await,所有异步操作必须塞进同步流程。查重类规则(如用户名唯一性)只能靠 $.ajax({ async: false }) 阻塞等待,再把错误字符串 return 出去,否则表单照常提交。
常见错误是只在 success 里设变量、没在函数末尾 return msg,或者用 layer.msg() 替代 return,这都不会阻断验证流程。
- 后端返回建议用标准 JSON,如
{"exists": true},别直接返回布尔值 - 编辑场景需排除自身 ID,从
item上读取隐藏字段:$(item).closest('form').find('input[name="id"]').val() - GET 请求注意 URL 编码,
value含特殊字符时用encodeURIComponent(value)
校验失败后怎么让红边框和提示立刻出现
只有 form.verify() 规则函数明确 return 非空字符串(如 "用户名已存在"),Layui 才会自动加 lay-form-danger 类、显示右侧图标、激活提示层。返回 undefined、true 或空字符串,就等于“通过”,不会有任何视觉反馈。
- 内置规则(如
required)自带提示,但自定义规则必须手动return提示文本 - 如果没看到红边框,先检查三处:
form.render('input')是否执行、input是否有name、lay-verify声明的规则名是否和form.verify()里定义的一致 - 不要手动给
input加lay-form-danger类——这是 Layui 内部控制的,强行加可能被后续校验覆盖
真正容易被忽略的是:手动改值后不触发 form.on('change'),提交时仍用旧值
Layui 的验证状态和 DOM 值不是强绑定的。比如你在 JS 里直接写 input.value = "abc",但没触发 form.on('change'),也没调 form.validate(),那么 form.val() 可能还是旧值,提交时发出去的就是错的。
失焦校验只是手段,核心目标是让数据、UI、验证状态三者同步。所以每次手动改值后,要么等用户自己失焦触发 change,要么主动调 form.validate(field) 强制重验——尤其在编辑回填、清空等操作后。


















