Flutter 中如何使用 Formz 实现密码确认与两次密码一致性校验
解决方案
Formz本身支持在自定义FormzInput中传入额外依赖参数,你只需要改造ConfirmPassword类,把原始密码作为构造参数传入即可,具体实现如下:
第一步:改造ConfirmPassword类
新增password属性存储原始密码,所有构造方法都新增对应参数:
class ConfirmPassword extends FormzInput<String, ConfirmedPasswordValidationError> { // 存储原始密码的属性 final String password; // 构造方法新增password参数 const ConfirmPassword.pure({this.password = ''}) : super.pure(''); const ConfirmPassword.dirty({required this.password, String value = ''}) : super.dirty(value); static final _confirmPasswordRegExp = RegExp(r'^[A-Za-z\d@$!%*?&]{8,}$'); @override ConfirmedPasswordValidationError? validator(String value) { if (value.isEmpty) { return ConfirmedPasswordValidationError.empty; } else if (!_confirmPasswordRegExp.hasMatch(value)) { return ConfirmedPasswordValidationError.invalid; } // 直接用类属性的password做比对即可 return password == value ? null : ConfirmedPasswordValidationError.mismatch; } }
第二步:调整密码变更的处理逻辑
原始密码修改后,要同步更新ConfirmPassword实例的依赖密码,避免校验逻辑用旧的原始密码比对:
void passwordChanged(String value) { final password = Password.dirty(value); // 同步更新确认密码的依赖原始密码 final updatedConfirmPassword = ConfirmPassword.dirty( password: password.value, value: state.confirmPassword.value, ); emit(state.copyWith( password: password, confirmPassword: updatedConfirmPassword, status: Formz.validate( [state.name, state.email, password, updatedConfirmPassword]), )); }
第三步:调整确认密码变更的处理逻辑
创建ConfirmPassword实例时传入当前已经输入的原始密码:
void confirmPasswordChanged(String value) { final confirmPassword = ConfirmPassword.dirty( password: state.password.value, value: value, ); emit(state.copyWith( confirmPassword: state.password.valid ? confirmPassword : const ConfirmPassword.pure(), status: Formz.validate( [state.name, state.email, state.password, confirmPassword]), )); }
补充说明
- 这是Formz官方推荐的依赖其他输入值的校验方案,不需要额外引入其他自定义逻辑
- 原始密码修改后同步更新确认密码实例,可以保证用户先输确认密码再改原始密码时,也能正确触发不匹配的校验提示
内容的提问来源于stack exchange,提问作者Alper Efe Sahin
相关产品推荐
相关产品推荐

