required未生效是因为浏览器原生校验需同时满足:表单在内、提交按钮为type="submit"、未阻止submit事件、未用js直接调form.submit();且仅text、email、number等可编辑控件支持,hidden等类型无效。

加了 required 却没拦住提交?不是属性写错了,而是它根本没被浏览器“看见”或“触发”。原生校验只在特定结构、特定类型、特定动作下才生效,缺一不可。
哪些 input 类型真正支持 required
浏览器只对具备「可编辑性」和「明确空值语义」的控件做校验,其他一律忽略:
-
text、email、number、tel、url、password、date、textarea✅ -
checkbox(表示“必须勾选”)、radio(同name下任一加即可)✅ -
select(需含<option value=""></option>,且不能设selected)✅ -
hidden、button、image、range、color、submit❌——写了也白写
特别注意:type="number" 输入框删光内容后,value 是空字符串 "",此时 required 才会生效;但若 JS 赋值为 " "(空格),它会被当作已填写,校验通过。
required 不触发校验的四个硬性条件
它不是“加了就管用”,而是依赖完整的表单上下文和用户动作:
- 表单必须包裹在
<form></form>内——脱离form,required形同虚设 - 提交按钮必须是
<button type="submit"></button>或<input type="submit">;type="button"或没写type(默认button)完全不触发 - 若在
submit事件里写了e.preventDefault(),必须手动调form.checkValidity(),否则校验被跳过 - 用 JS 直接调
form.submit()—— 这个调用绕过所有原生校验逻辑,required失效
移动端还要额外提防:iOS Safari ≤15.4 对 type="file" 和 type="select" 的 required 支持不稳定,建议加 JS 降级兜底。
select 和 radio 的坑最容易踩
这两类控件的“空值判断”逻辑和文本框不同,稍不注意就绕过校验:
-
<select required><option value="">请选择</option></select>❌ 默认选中空值,用户不动它就通过校验 - 正确写法:
<option value="" disabled hidden selected>请选择</option>——disabled让它不可选,hidden防止显示,selected确保初始状态 -
radio组里只给其中一个加required是合法的,但必须确保同name下至少有一个未被disabled;如果全 disabled,校验也会失效
别依赖 placeholder 或 label 文字来暗示必填——浏览器只看 value 属性值是否为空字符串 ""。
自定义提示文案的唯一可靠方式
浏览器原生提示(如 Chrome 的“请填写此字段”)无法用 HTML/CSS 修改,只能用 JS 干预:
- 在输入框上监听
input或blur,检查value.trim() === "" - 为空时调
input.setCustomValidity("手机号不能为空") - 非空时**必须立刻**调
input.setCustomValidity("")—— 否则后续即使填了内容,提交仍报错 - 不要在
input事件里反复调setCustomValidity,容易污染浏览器内部校验状态
最常被忽略的一点:服务端永远要二次校验。前端 required 可被禁用、绕过、伪造,它只是体验层的守门员,不是安全锁。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











