form.val 拿不到值是因为未正确建立缓存,需确认模块已加载、lay-filter 存在且拼写一致、动态表单调用 form.render();取值应优先用 form.on('submit') 获取 data.field。

form.val 为什么拿不到值?常见原因和检查点
直接调用 form.val('formFilter') 返回空对象,大概率不是 API 用错了,而是表单没被正确识别。Layui 的 form.val 不读 DOM 属性,只读它自己管理的「表单数据缓存」——这个缓存只在以下时机自动建立或更新:渲染 form 模块时(form.render())、用户交互触发 lay-filter、或手动调用 form.val('filter', data) 设置过。
所以第一步先确认:form 模块是否已加载并渲染?form 元素是否有正确的 lay-filter 属性?有没有在 JS 执行前就操作了表单?
- 检查 HTML 中
<form lay-filter="demoForm"></form>是否存在且拼写一致 - 确保
layui.use(['form'], function(){...})内执行form.val,而不是全局作用域 - 如果表单是动态插入的(比如 AJAX 加载),必须手动调用
form.render('select')或form.render()补全事件绑定
form.val('filter') 和 form.val('filter', obj) 的区别
form.val('filter') 是「取值」,返回一个键值对对象,key 是表单元素的 name 属性值,value 是当前控件的值(input 取 value,select 取选中项的 value,checkbox/radio 取被勾选的 value 数组)。
form.val('filter', obj) 是「赋值」,用于初始化或重置表单。注意:它不会触发 change 事件,也不会自动同步到 DOM 的 value 属性(但 Layui 内部会更新其缓存,并刷新显示)。
- 取值时若某个
name重复(如多个 checkbox 共用同一 name),form.val返回的是数组,不是字符串 - 下拉框
select若未设置value,而只靠selected属性,默认取的是innerText,容易出错,务必显式写<option value="1">男</option> -
form.val对textarea和普通input一视同仁,都取value;但如果你用 JS 直接改了textarea.innerText,form.val仍读value,可能不一致
没有 lay-filter 怎么办?用原生方式兜底
有些场景(比如表单结构混乱、或部分控件没走 Layui 渲染),form.val 失效。这时别硬扛,直接切原生 DOM 获取:
const formElem = document.querySelector('#myForm');
const formData = new FormData(formElem);
const data = {};
for (let [key, value] of formData.entries()) {
if (!data[key]) {
data[key] = value;
} else if (Array.isArray(data[key])) {
data[key].push(value);
} else {
data[key] = [data[key], value];
}
}
这个方案兼容所有标准表单控件,包括文件上传(FormData 自动处理),且不依赖 Layui 的内部状态。缺点是:无法获取 Layui 封装的开关(switch)、评分(rate)等非原生组件的值——这些必须单独查 elem.checked 或 elem.value。
- 开关(
switch)实际是隐藏的checkbox+ 样式层,读它的checked属性即可 - 日期/时间选择器(
laydate)的值存在绑定的 input 的value里,直接取 DOM 的value - 富文本(
layedit)需调用layedit.getContent(id),不能靠form.val
form.on('submit(...)') 里取值最稳妥
如果目标是提交时获取全部值,最可靠的方式不是手动调 form.val,而是监听 submit 事件:
form.on('submit(demoForm)', function(data){
console.log(data.field); // 这就是所有已填字段组成的对象
return false; // 阻止页面跳转
});
这个 data.field 是 Layui 在表单提交瞬间从 DOM 实时采集的,绕过了缓存机制,也兼容动态增删的控件(只要它们有 name 且在 form 内)。比手动调 form.val 更贴近真实提交行为。
注意:如果用了 ajax 提交,别忘了在 success 后手动重置表单(form.val('demoForm', {}))或清空 DOM(formElem.reset()),否则下次提交可能带着旧值。
真正麻烦的从来不是怎么取值,而是哪些值根本没进 Layui 的视野——比如漏写 name、动态插入后忘了 form.render()、或者混用了原生控件和 Layui 组件却没统一管理。盯住 name 和 lay-filter 这两个属性,90% 的问题就消失了。











