required不生效主因是“假提交”:button未设type="submit"、js调用form.submit()、input未嵌套在form内,或移动端webview兼容性差需checkvalidity()兜底。

required 不生效?先看是不是“假提交”
加了 required 却没拦住空提交,90% 是因为没走浏览器原生提交流程。它只在真正的表单提交时触发,不是写上就自动监听输入。
-
<button>提交</button>没写type="submit"—— 默认是type="button",完全绕过验证 - JS 调用
form.submit()—— 这个方法不触发任何原生校验,应改用form.requestSubmit() -
<input required>没包在<form></form>内部 —— 浏览器压根不识别它的验证语义 - 移动端某些 WebView(如旧版 Android 系统)会忽略
required,需配合checkValidity()做兜底
pattern 正则总匹配失败?检查类型和写法
pattern 只对 type="text"、"email"、"tel"、"url"、"password" 有效;对 type="number" 或 "date" 完全无效 —— 浏览器会在正则执行前就把值转成数字或日期对象,导致字符串匹配失败。
- 正则不能写
^和$,浏览器自动锚定,写了反而报Invalid regular expression -
\d在部分 Safari 版本中不匹配 Unicode 数字,建议显式写[0-9] - 中文要写成
[\u4e00-\u9fa5](注意无反斜杠转义),\u4E00-\u9FA5格式在旧 Chrome 会解析失败 - 手机号别只写
pattern="\d{11}",应写pattern="1[3-9]\d{9}",避免匹配到纯数字乱码 -
pattern不校验空值,空字段由required控制,两者得共存才能既防空又防格式错
setCustomValidity 后提示一直挂着?漏清空是最大坑
setCustomValidity() 设了非空字符串后,该字段就永远处于 invalid 状态,直到你手动传空字符串清空。这不是 bug,是设计行为。
- 不要只在
invalid事件里设错误 —— 它触发时已晚,且不覆盖旧错误 - 推荐在
input或blur事件第一行就调el.setCustomValidity(""),再做逻辑判断 - 异步校验(如用户名是否可用)返回后,成功时必须立刻调
el.setCustomValidity(""),否则下次提交仍被阻断 - 修改
setCustomValidity后,必须再触发一次验证(如blur、submit或手动调checkValidity())才会更新:invalid伪类
preventDefault() 后验证气泡消失?你接管了就得自己干完
一旦在 submit 事件里用了 event.preventDefault(),浏览器原生验证气泡和阻断逻辑就彻底失效。这不是“禁用”,而是“交出控制权”。
- 别指望
input.reportValidity()在 preventDefault 后还能弹出气泡 —— 它只在未被拦截的 submit 中可靠 - 手动提示建议插入到对应
input的相邻位置(如nextElementSibling),并加aria-live="polite"保证读屏器可感知 - 校验失败后,记得给第一个出错字段调
focus(),否则用户可能根本看不到哪错了 - 用
checkValidity()+setCustomValidity()本身不会阻止提交,必须在submit事件里显式判断并preventDefault()
submit()、autocomplete 缺失导致 Chromium 主动降级、隐藏元素上调用 reportValidity() 无声无息、或者服务端返回字段名和 name 属性大小写/下划线不一致却没清理旧提示。这些细节一漏,问题就藏得深。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











