通用表单校验插件需显式声明规则、精准绑定时机、支持可中断验证链;依赖queryselectorall扫描必漏动态/自定义字段;须用data-validate标记字段,支持分隔符与参数,避免name冲突;按类型分层响应事件;为非标字段预留getter钩子;validate()必须返回promise以支持异步校验。

直接说结论:通用表单校验插件不靠“全自动识别”,而靠显式声明规则 + 精准绑定时机 + 可中断的验证链;强行用 querySelectorAll('input') 扫一遍再统一校验,90% 的场景会漏掉动态字段、复选组、自定义控件或异步加载内容。
怎么让校验规则和 DOM 元素真正对得上
常见错误是把规则写死在 JS 对象里,比如 { email: 'required|email' },但没指定这个 email 对应哪个 input[name="email"] 或哪个 data-field="email"。结果表单一有多个同名字段(如地址表单中“收货邮箱”“发票邮箱”),规则就错配。
- 推荐用
data-validate属性显式标记需校验的字段,例如<input name="phone" data-validate="required|mobile"> - 规则解析函数必须支持分隔符(如
|)和参数(如min:6),不能只认固定字符串 - 避免依赖
name值做唯一键——name可能重复、可能为空、可能被后端忽略;优先用id或新增data-field-id
blur、submit 还是 input 时触发校验
用户填完立刻标红,体验差;全等 submit 才报错,又太晚。关键不是“选哪个事件”,而是按字段类型分层响应:
-
input[type="email"]、input[type="tel"]:监听blur+input(防粘贴),但加setTimeout防抖(避免每敲一个字都验) - 下拉选择(
select)、单选/复选组(name相同的input[type="radio/checkbox"]):只监听change - submit 时:强制执行全部字段的终审,包括那些用户还没点过的字段(比如隐藏的 token 字段)
别用 oninput 绑定所有输入框——它不触发于粘贴、拖拽、自动填充,且移动端软键盘回车不会触发。
如何处理复选组、文件上传、富文本等非标字段
校验插件如果只认 value,就会在 input[type="file"] 上拿到 "C:\fakepath\xxx.jpg",在 div[contenteditable] 上读不到真实内容,对 checkbox 组只会取第一个的 checked 状态。
- 为特殊字段预留
getter钩子:插件初始化时允许传入{ getFileValue(el) { return el.files?.[0]; }, getEditorValue(el) { return el.innerText; } } - 复选组统一用
document.querySelectorAll('[name="hobbies"]:checked')获取全部选中项,再交由规则(如min:2)判断长度 - 文件字段默认不参与 submit 校验,除非显式设置
data-validate="required|size:2mb"并提供size规则实现
为什么 validate() 方法返回 Promise 而不是布尔值
因为真实业务里,“是否通过”常依赖异步判断:手机号是否已注册、邀请码是否有效、图片 OCR 是否识别出身份证号。同步返回 true/false 会让插件无法等待这些结果,要么假成功,要么卡 UI。
-
validate()必须返回Promise }> - 每个字段的单条规则可返回
Promise<boolean></boolean>或同步布尔值,插件内部用Promise.allSettled()汇总 - 提交按钮要
disabled直到 Promise resolve,而不是靠valid字段临时锁住——否则用户连点两次 submit,会发多次请求
最容易被忽略的是:异步规则失败时,错误信息必须能定位到具体字段,而不是笼统抛出 "校验未完成";这要求每个异步校验调用都携带字段标识(fieldId),并在 reject 时附带上下文。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











