浏览器原生校验不足因仅提交时触发、提示不可控、不支持异步;需输入即校验、同步/异步规则、可编程错误信息及响应式状态管理,核心是纯函数校验、requestIdleCallback防抖、集中式formState与submit拦截聚合错误。

为什么直接用 required 和 pattern 不够用
浏览器原生校验只在提交时触发,且错误提示不可控、样式无法统一,更没法做异步验证(比如检查用户名是否已存在)。用户输入过程中没反馈,体验断层;表单字段多时,手动监听每个 input 事件+维护状态容易出错。
真正需要的是:输入即校验、支持同步/异步规则、错误信息可编程控制、状态可响应式消费。
关键点:addEventListener('input') 太粗放,onchange 又太迟——应优先用 input 事件 + requestIdleCallback 防抖,避免卡顿。
如何让单个字段校验逻辑可复用又不耦合 DOM
把校验抽成纯函数,输入是值和额外参数,输出是 { valid: boolean, message: string }。不操作 DOM,不读取 dataset,也不依赖 this。
立即学习“前端免费学习笔记(深入)”;
示例规则函数:
const emailRule = (value) => {
const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return {
valid: re.test(value),
message: value ? '邮箱格式不正确' : '请输入邮箱'
};
};
多个规则用数组组合,顺序执行,遇到第一个 valid: false 就停止:
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
-
required规则必须放最前,避免空值进正则报错 - 异步规则(如用户名查重)返回
Promise,需单独处理 pending 状态 - 不要在规则里直接修改
input.value——那是 UI 层的事
怎样让表单整体状态可响应式更新
不能靠反复遍历所有字段 DOM 获取值,应该用一个 JS 对象集中管理字段值和校验结果,例如:
const formState = {
email: { value: '', error: '', pending: false },
username: { value: '', error: '', pending: false }
};
每次输入更新对应字段的 value,再调用校验函数更新 error 和 pending。UI 层仅订阅这个对象(可用 Proxy 或框架响应式系统)。
注意点:
- 字段名必须和
name属性严格一致,否则无法映射 - 提交前要主动触发一次全量校验,不能只信实时结果(比如用户删掉输入后没再触发 input 事件)
- 重置表单时,要同时清空
value、error、pending,不能只设value = ''
提交时如何阻断原生行为并聚合错误
给 form 绑定 submit 事件,第一件事就是 event.preventDefault()。然后遍历 formState,收集所有 error 非空的字段。
如果全部通过,才调用真实提交逻辑(如 fetch);否则聚焦第一个出错字段,并滚动到可视区:
const firstInvalid = Object.entries(formState).find(([, v]) => v.error);
if (firstInvalid) {
const field = document.querySelector(`[name="${firstInvalid[0]}"]`);
field?.focus();
field?.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
容易漏的细节:
- 禁用提交按钮时,记得同时设置
aria-disabled="true",保障无障碍 - 异步校验未完成(
pending: true)的字段,不能算“通过”,得等 Promise settle - 服务端返回的错误(如“密码太简单”)要能反向注入到对应字段的
error中,而不是弹全局 alert
复杂点不在写多少代码,而在字段生命周期管理——输入、失焦、提交、重置、异步返回,每个环节都要对齐状态,稍有遗漏就会出现“明明错了但没提示”或“提示了却无法提交”。


















