layui.form.val()不区分脏数据,需手动比对初始值与当前值;应在layui.form.render()后立即保存快照,注意checkbox/radio的key缺失问题,并单独处理动态字段和lay-ignore控件。
layui.form.val() 本身不区分脏数据,得自己比对
layui 没有内置的「只取修改过字段」api。layui.form.val('filter') 拿到的是当前所有有效值(忽略 disabled 和 lay-ignore),但不管它是不是被用户改过。所谓“脏数据”,本质是和初始值做差异比对,这个逻辑必须由你控制。
保存初始值的两个可靠时机
关键不是“怎么取”,而是“拿什么去比”。初始值必须在用户操作前固化下来:
- 表单首次渲染后、用户还没动之前,立即调用
layui.form.val('filter')存一份快照(比如挂到form.dataset.initial或全局变量) - 如果是服务端返回的 JSON 渲染表单(如
form.val('filter', data)赋值后),那赋值前的data就是天然初始值,直接保留引用即可 - 别在 DOM 加载完就立刻存——要等
layui.form.render()执行完毕,否则 checkbox/radio 状态可能未同步,快照不准
比对时注意 checkbox 和 radio 的结构差异
脏数据比对不能简单用 JSON.stringify 全量对比,因为:
-
checkbox组在初始值里可能是{hobby: ["read"]},用户取消勾选后form.val()返回的对象里压根没有hobby字段(不是hobby: []),直接 key 对比会漏判 -
radio未选中时同样不出现对应 key,而初始值里它存在且有值,这种“key 缺失”就是典型脏状态 - 建议用工具函数逐 key 判断:
initial[key] !== current[key],对不存在的 key 单独处理(如!(key in current) && (key in initial))
动态字段和 lay-ignore 会让脏检测失效
如果表单支持增删行(如动态添加的 input),这些字段不会自动进入初始快照,比对时永远算“脏”。解决方案只有两个:
- 每次新增字段后,手动把它的 name + 初始 value 补进初始快照对象(注意数组 name 如
item[0].name要按 layui 内部解析规则归一化) - 换思路:不依赖初始值,改用事件监听——给所有表单项绑定
change或input,记录被触发过的 name,提交时只取这些 name 的当前值(但要注意 disabled 和 lay-ignore 元素需过滤)
lay-ignore 容器里的自定义控件(比如富文本编辑器),它们的值不在 form.val() 范围内,却可能是业务关键字段。这类字段必须单独初始化、单独监听、单独比对。











