如何使用Angular 12 Material实现密码与确认密码校验?
Angular Material 12 密码与确认密码匹配校验实现
你当前代码的核心问题是两个密码输入框绑定了同一个passwordFormControl,会导致输入值互相覆盖,根本无法分别取值做匹配校验。密码匹配属于跨字段校验,需要基于FormGroup挂载自定义验证器实现,完整实现步骤如下:
1. 编写组件TS逻辑
首先引入响应式表单相关依赖,编写自定义密码匹配验证器,将两个密码控件包裹在同一个FormGroup中,把验证器挂载到FormGroup层级:
import { Component, OnInit } from '@angular/core'; import { FormGroup, FormControl, Validators, AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms'; // 自定义密码匹配验证器 export const passwordMatchValidator: ValidatorFn = (control: AbstractControl): ValidationErrors | null => { const password = control.get('password'); const confirmPassword = control.get('confirmPassword'); return password && confirmPassword && password.value !== confirmPassword.value ? { passwordMismatch: true } : null; }; @Component({ selector: 'app-password-form', templateUrl: './password-form.component.html' }) export class PasswordFormComponent implements OnInit { // 控制密码显隐 hide = true; // 表单组定义 passwordForm = new FormGroup({ password: new FormControl('', [Validators.required, Validators.minLength(6)]), confirmPassword: new FormControl('', [Validators.required]) }, { validators: passwordMatchValidator }); ngOnInit(): void { // 实现密码输入时确认密码实时校验 this.passwordForm.controls.password.valueChanges.subscribe(() => { this.passwordForm.controls.confirmPassword.updateValueAndValidity(); }); } // 快捷获取表单控件 get formControls() { return this.passwordForm.controls; } }
2. 修正模板HTML代码
替换原来绑定同一个FormControl的写法,改用formControlName绑定对应控件,补全错误提示逻辑:
<form [formGroup]="passwordForm"> <div> <mat-form-field> <mat-label>Password</mat-label> <input matInput placeholder="Digite sua senha" [type]="hide ? 'password' : 'text'" formControlName="password" /> <mat-icon matSuffix (click)="hide = !hide"> {{ hide ? 'visibility' : 'visibility_off' }} </mat-icon> <mat-error *ngIf="formControls.password.errors?.required"> 密码不能为空 </mat-error> <mat-error *ngIf="formControls.password.errors?.minlength"> 密码长度不能少于6位 </mat-error> </mat-form-field> </div> <div> <mat-form-field> <mat-label>Confirm Password</mat-label> <input matInput placeholder="Digite novamente sua senha" [type]="hide ? 'password' : 'text'" formControlName="confirmPassword"/> <mat-icon matSuffix (click)="hide = !hide"> {{ hide ? 'visibility' : 'visibility_off' }} </mat-icon> <mat-error *ngIf="formControls.confirmPassword.errors?.required"> 请再次输入密码 </mat-error> <mat-error *ngIf="passwordForm.errors?.passwordMismatch && !formControls.confirmPassword.errors?.required"> 两次输入的密码不一致 </mat-error> </mat-form-field> </div> </form>
关键注意点
- 禁止给两个存在独立校验逻辑的输入框绑定同一个
FormControl,会导致值联动覆盖,完全无法实现差异化校验 - 跨字段关联校验必须挂载在两个控件共同的父级
FormGroup上,不要单独绑定到某一个控件上,否则修改其中一个字段时,另一个字段的错误状态不会自动同步更新 - 密码显隐的逻辑可以复用同一个
hide变量,点击任意一个输入框的眼睛图标会同步控制两个密码框的显隐状态,符合常规交互逻辑
内容的提问来源于stack exchange,提问作者Leogomes
相关产品推荐
相关产品推荐

