uni-forms 的 rules 不生效根本原因是 rules 键名必须与 model 顶层字段名完全一致,不支持嵌套路径;需确保 model 响应式、正则加^$、异步校验返回 Promise 并调用 callback。

uni-forms 的 rules 配置为什么总不生效?
根本原因是 rules 必须和 model 的字段名完全一致,且 uni-forms 不支持嵌套路径(如 user.name)直接校验。如果你的表单数据是深层对象,得 flatten 后映射,或者改用 validateField 手动触发。
常见错误现象:uni-forms 提交无反应、控制台没报错但校验提示不显示、某字段始终标红却无文字提示。
- 确保
model是响应式对象(ref({})或reactive({})),不能是普通字面量 -
rules中每个 key 必须与model的顶层 key 严格对应,比如model: { phone: '' }→rules: { phone: [...] } - 正则校验写法要加
^和$,否则/1[3-9]\d{9}/会误判 "abc13812345678def" - 异步校验(如用户名是否已存在)必须返回 Promise,并在 resolve/reject 前调用
callback(),否则卡住
如何动态添加/删除表单项并保持校验联动?
uni-forms 本身不监听数组长度变化,v-for 渲染的子项不会自动注册进校验系统。必须配合 addRule 和 removeRule 主动管理规则,同时用 clearValidate 清除旧状态。
使用场景:地址列表、多图上传、技能标签组等可增删的字段块。
- 每次 push 新项时,立刻调用
formRef.value.addRule('field_0', rules),其中 key 要唯一(建议用时间戳或索引拼接) - 删除项前,先
formRef.value.removeRule('field_0'),再从 model 数组中 splice - 避免用
index作为 rule key —— 数组重排后 key 错位会导致校验残留 - 批量操作后建议调用
formRef.value.clearValidate(),防止缓存状态干扰
自定义校验规则里怎么访问其他字段值?
uni-forms 的 validator 函数默认只传当前值和回调,但你可以通过闭包或 ref 拿到整个 model。更稳妥的做法是把依赖字段也声明为 rule key,用 trigger: 'change' 触发联动校验。
典型需求:确认密码需等于密码、结束时间不能早于开始时间。
- 不要在
passwordConfirm的 validator 里直接读model.password—— 可能是旧值;应设trigger: 'change'并在函数内取最新值 - 多个字段强关联时,建议统一收口到一个
custom校验函数,手动调用formRef.value.validateField(['start', 'end']) - 日期类比较注意时区,
new Date(value).getTime()比字符串比对更可靠
提交时 validate 失败但 error-message 不显示?
大概率是 uni-forms-item 缺少 name 属性,或该 name 和 rules key 不匹配。uni-forms 依靠 name 关联字段与规则,没有它就无法定位错误来源。
性能影响:频繁调用 validate() 会遍历全部规则,含异步校验时可能阻塞 UI,务必加 loading 状态。
- 每个
uni-forms-item必须有name,且值等于model的键名(如name="email"对应model.email) - 如果用了
label-position="top"或自定义插槽,仍需保留name,否则校验结果无法渲染到对应位置 - 提交前建议先
formRef.value.clearValidate(),避免上次失败的提示残留覆盖新结果 - catch validate 的 promise reject,打印
detail.reason查具体哪个字段失败,比看 UI 更准
最易被忽略的是:uni-forms 在 H5 和小程序端对 input 事件的兼容性不同,真机调试时务必验证 blur/change 触发时机 —— 尤其是 iOS 微信内置浏览器,有时需要显式绑定 @blur 并手动调用 validateField。











