HTML原生required属性足够实现必填校验,无需JS;仅作用于input/select/textarea,需在表单内且避免type="button"提交;自定义提示须用setCustomValidity()动态控制;React/Vue中需避免value为null/undefined导致误触发;后端必须重复校验,因required非安全机制。

HTML 原生 required 属性就足够了
直接在 <input> 标签上加 required 属性,浏览器会自动阻止表单提交,并聚焦到该输入框,同时显示默认提示(如 “请填写此字段”)。不需要 JS、不需要额外配置,这是最轻量、最可靠的必填校验起点。
常见错误是以为必须搭配 name 或 id 才能生效——其实只要标签合法、在表单内,required 就起作用。但注意:如果表单用 button type="button" 提交(绕过原生 submit 事件),required 会完全不触发。
-
<input type="text" required>✅ 有效 -
<input type="text" required="">✅ 等价写法 -
<input type="text" required="false">❌ 无效(布尔属性不认值) -
<div contenteditable required>❌ 不支持,仅适用于可提交的表单控件(input、select、textarea)
如何自定义 required 的错误提示文案
浏览器默认提示无法通过 HTML 属性修改,必须用 JS 调用 setCustomValidity() 干预。关键点在于:只要传入非空字符串,就会覆盖原生提示;传入空字符串,才恢复原生校验逻辑。
典型误操作是只调一次 setCustomValidity('必填'),之后即使用户输入内容,校验状态仍卡在“无效”。必须配合 input 或 blur 事件动态清空:
立即学习“前端免费学习笔记(深入)”;
<input id="username" required>
<script>
const el = document.getElementById('username');
el.addEventListener('input', () => {
if (el.value.trim()) {
el.setCustomValidity(''); // 恢复原生校验
} else {
el.setCustomValidity('用户名不能为空');
}
});
</script>
React/Vue 中绑定 required 要小心受控与非受控切换
在 React 中,如果给 <input required value={value} onChange={...} /> 加了 required,但初始 value 是 undefined 或 null,会导致首次渲染时元素被判定为“空值”,触发浏览器红框+焦点锁定——哪怕用户还没开始输入。
根本原因是:受控组件的 value 为 null/undefined 时,DOM 实际值为空字符串,而 required 正好校验这个空字符串。
- ✅ 安全做法:初始化
value为''(空字符串) - ✅ 或改用非受控模式:
defaultValue+ref获取值 - ❌ 避免
value={null}或value={undefined}配合required - Vue 同理:
:value="null"也会触发相同问题
后端不能只信 required,但前端必须用它
required 是用户体验层的守门人,不是安全机制。它可能被禁用(开发者工具删掉属性)、绕过(直接 fetch 提交)、或在 JS 错误时彻底失效。所以后端必须重复校验,且不能依赖前端传来的“是否必填”元数据。
但前端不用 required 也不行:它提供无障碍支持(屏幕阅读器识别必填)、键盘导航兼容性(Tab 到必填项时有视觉反馈)、以及零 JS 降级体验。如果你为了“统一校验逻辑”而全用 JS 实现必填,反而会丢失这些基础能力。
真正容易被忽略的是:当多个必填项并存时,浏览器只聚焦第一个未填项,不会高亮全部。如需全量提示,得自己监听 submit 事件遍历验证——但别删掉 required,它是底层支撑。


















