应识别校验逻辑中可复用的职责切分点再按需引入设计模式:strategy适配多场景规则切换,observer解耦多字段联动,composite管理fieldset分组校验。

直接用设计模式套表单校验,90%会加重耦合、拖慢开发。真正该做的是识别校验逻辑中可复用的**职责切分点**,再按需引入对应模式,而不是先选模式再硬套。
为什么 Strategy 模式比 Validation 类更适配校验规则切换
当你需要在不同环境(如注册页/修改页/后台管理)复用同一类校验逻辑(比如手机号格式),但提示文案、错误级别、是否触发埋点各不相同,Strategy 就比写一个大而全的 Validation 类清晰得多。
常见错误是把所有规则塞进一个对象,靠 if-else 分支判断场景,结果每次加个新字段就得改主逻辑;而 Strategy 把每条规则封装成独立函数或类,通过 ruleMap 映射到 data-rule-id,新增规则只需注册新策略,不碰旧代码。
- 每个策略函数接收
value和context(含字段名、页面类型等),返回{ valid: boolean, message: string, level: 'error' | 'warn' } - 初始化时用
document.querySelectorAll('[data-rule-id]')扫描所有字段,按data-rule-id查找对应策略,绑定input事件 - 避免把 DOM 元素传进策略函数——策略只管“值对不对”,UI 反馈由外层统一处理
Observer 模式解决多字段联动校验的触发混乱
当「密码」和「确认密码」必须一致、「省份」变更后「城市」下拉要重载、「是否开票」勾选后「发票抬头」才变必填——这类依赖关系如果用一堆 addEventListener 硬绑,很快变成回调地狱。
Observer 不是为炫技,而是把“谁被改了”和“谁该响应”解耦。核心不是监听 input,而是监听字段的 validity 或自定义状态变化。
- 每个字段维护一个
Subject实例,调用notify()仅当值变更且通过基础校验(如非空、格式合法) - 联动字段作为
Observer订阅相关 subject,例如「确认密码」订阅「密码」subject,收到通知后立即比对并更新自身状态类 - 禁止在 observer 回调里再触发另一个 notify——这会导致循环通知,用
isNotifying标志位拦截
Composite 模式管理 fieldset 分组校验的边界问题
fieldset 天然适合 Composite:它本身可校验(如要求至少一个子选项被选中),其子控件也可单独校验。但浏览器原生 checkValidity() 不递归,直接调用只会检查直系子元素。
手动实现 Composite 校验树,关键在明确“组合节点”和“叶子节点”的行为差异:
- 叶子节点(
input、select)直接调用element.checkValidity() - 组合节点(
fieldset)遍历所有直系表单控件,聚合结果;若含嵌套fieldset,递归调用其validate()方法 - 必须跳过被
disabled的控件——它们的值不提交,也不应参与校验,否则reportValidity()会弹出无关提示 - 聚合逻辑别用“全通过才算通过”,而是按业务定:比如「收货信息」组允许地址为空但手机号必填,就需策略化判定
最易被忽略的是 fieldset 的 disabled 继承断裂——只要中间插了个 div,内部控件就脱离校验树。上线前务必用键盘 Tab 测试焦点是否跳过所有 disabled 字段,这是唯一可靠验证方式。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











