OpenHarmony PC多字段表单验证 - 用Flutter实现
·

案例概述
本案例展示如何构建一个包含多个验证规则的表单,包括用户名长度验证、密码强度验证、密码一致性验证、手机号格式验证等。
核心概念
1. 验证规则
- 长度验证:检查字符串长度;
- 格式验证:使用正则表达式检查格式;
- 跨字段验证:比较多个字段的值。
2. 正则表达式
RegExp(r'[A-Z]'):检查是否包含大写字母;RegExp(r'[0-9]'):检查是否包含数字;RegExp(r'^1[3-9]\d{9}$'):检查手机号格式。
3. 错误消息
- 清晰的错误提示;
- 指导用户如何修正。
代码详解
1. 用户名验证
validator: (value) {
if (value == null || value.isEmpty) return '用户名不能为空';
if (value.length < 3) return '用户名至少 3 个字符';
if (value.length > 20) return '用户名最多 20 个字符';
return null;
}
2. 密码强度验证
validator: (value) {
if (value == null || value.isEmpty) return '密码不能为空';
if (value.length < 6) return '密码至少 6 个字符';
if (!value.contains(RegExp(r'[A-Z]'))) return '密码必须包含大写字母';
if (!value.contains(RegExp(r'[0-9]'))) return '密码必须包含数字';
return null;
}
3. 跨字段验证
validator: (value) {
if (value != _password) return '两次输入的密码不一致';
return null;
}
4. 手机号验证
validator: (value) {
if (!RegExp(r'^1[3-9]\d{9}$').hasMatch(value)) {
return '请输入有效的手机号';
}
return null;
}
高级话题:表单验证的深度应用
1. 异步验证
某些验证需要调用服务器 API:
validator: (value) async {
if (value == null || value.isEmpty) return '用户名不能为空';
final isAvailable = await checkUsernameAvailability(value);
if (!isAvailable) return '用户名已被占用';
return null;
}
2. 自定义验证器
创建可复用的验证函数:
String? validateEmail(String? value) {
if (value == null || value.isEmpty) return '邮箱不能为空';
if (!value.contains('@')) return '请输入有效的邮箱';
return null;
}
TextFormField(
validator: validateEmail,
)
3. 条件验证
根据其他字段的值进行验证:
validator: (value) {
if (_userType == 'business' && (value == null || value.isEmpty)) {
return '企业用户必须填写营业执照';
}
return null;
}
4. 实时验证反馈
在用户输入时显示验证状态:
TextFormField(
onChanged: (value) {
setState(() {
_passwordStrength = calculateStrength(value);
});
},
decoration: InputDecoration(
suffixIcon: _passwordStrength > 0.7
? Icon(Icons.check_circle, color: Colors.green)
: null,
),
)
5. 密码强度指示器
LinearProgressIndicator(
value: _passwordStrength,
backgroundColor: Colors.grey.shade300,
valueColor: AlwaysStoppedAnimation(
_passwordStrength > 0.7 ? Colors.green : Colors.orange,
),
)
6. 表单验证的性能优化
避免在每次输入时都进行昂贵的验证:
Timer? _debounce;
void _onUsernameChanged(String value) {
_debounce?.cancel();
_debounce = Timer(const Duration(milliseconds: 500), () {
_validateUsername(value);
});
}
7. 多语言错误提示
String getErrorMessage(String key, BuildContext context) {
final locale = Localizations.localeOf(context);
if (locale.languageCode == 'zh') {
return {
'empty': '不能为空',
'invalid': '格式不正确',
}[key] ?? '';
}
return {
'empty': 'Cannot be empty',
'invalid': 'Invalid format',
}[key] ?? '';
}
8. 表单验证的状态管理
使用 Provider 或其他状态管理库管理表单状态:
class FormProvider extends ChangeNotifier {
String _username = '';
String? _usernameError;
void setUsername(String value) {
_username = value;
_usernameError = validateUsername(value);
notifyListeners();
}
}
9. 表单提交的错误处理
void _submitForm() async {
if (_formKey.currentState!.validate()) {
try {
await submitForm(_formData);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('提交成功')),
);
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('提交失败:$e')),
);
}
}
}
10. 表单验证的测试
test('验证用户名长度', () {
expect(validateUsername('ab'), isNotNull); // 太短
expect(validateUsername('abc'), isNull); // 正确
expect(validateUsername('a' * 21), isNotNull); // 太长
});
通过掌握这些高级验证技巧,你可以构建出健壮、用户友好的表单系统。
高级话题:表单验证的企业级应用
1. 验证规则引擎
创建可复用的验证规则:
class ValidationRule {
final String name;
final String Function(String?) validator;
ValidationRule({required this.name, required this.validator});
}
final emailRule = ValidationRule(
name: 'email',
validator: (value) {
if (value == null || value.isEmpty) return '邮箱不能为空';
if (!value.contains('@')) return '邮箱格式不正确';
return null;
},
);
2. 服务器端验证
与后端 API 协作进行验证:
Future<String?> validateUsernameOnServer(String username) async {
try {
final response = await http.post(
Uri.parse('https://api.example.com/validate-username'),
body: {'username': username},
);
if (response.statusCode == 200) {
final data = jsonDecode(response.body);
return data['available'] ? null : '用户名已被占用';
}
} catch (e) {
return '验证失败,请稍后重试';
}
return null;
}
3. 验证结果的可视化反馈
TextFormField(
onChanged: (value) {
setState(() {
_validationState = _validateField(value);
});
},
decoration: InputDecoration(
suffixIcon: _validationState == null
? Icon(Icons.check_circle, color: Colors.green)
: _validationState!.isNotEmpty
? Icon(Icons.error_circle, color: Colors.red)
: null,
),
)
4. 批量验证
一次验证多个字段:
Map<String, String?> validateAllFields() {
return {
'username': validateUsername(_usernameController.text),
'password': validatePassword(_passwordController.text),
'email': validateEmail(_emailController.text),
};
}
bool hasErrors(Map<String, String?> results) {
return results.values.any((error) => error != null);
}
5. 验证的国际化
支持多语言验证错误提示:
class ValidationMessages {
static final Map<String, Map<String, String>> messages = {
'zh': {
'empty': '不能为空',
'invalid_email': '邮箱格式不正确',
'password_weak': '密码强度不足',
},
'en': {
'empty': 'Cannot be empty',
'invalid_email': 'Invalid email format',
'password_weak': 'Password is too weak',
},
};
static String get(String key, String locale) {
return messages[locale]?[key] ?? messages['en']![key]!;
}
}
6. 验证的性能优化
使用防抖避免频繁验证:
Timer? _validationDebounce;
void _onFieldChanged(String value) {
_validationDebounce?.cancel();
_validationDebounce = Timer(Duration(milliseconds: 500), () {
setState(() {
_fieldError = validateField(value);
});
});
}
7. 验证的缓存
缓存验证结果,避免重复验证:
final Map<String, String?> _validationCache = {};
String? validateWithCache(String fieldName, String value) {
final cacheKey = '$fieldName:$value';
if (_validationCache.containsKey(cacheKey)) {
return _validationCache[cacheKey];
}
final result = _validateField(value);
_validationCache[cacheKey] = result;
return result;
}
8. 验证的链式调用
class FieldValidator {
String? _error;
FieldValidator notEmpty(String value, String message) {
if (_error == null && (value.isEmpty)) {
_error = message;
}
return this;
}
FieldValidator minLength(String value, int length, String message) {
if (_error == null && value.length < length) {
_error = message;
}
return this;
}
String? validate() => _error;
}
// 使用
final error = FieldValidator()
.notEmpty(_username, '用户名不能为空')
.minLength(_username, 3, '用户名至少 3 个字符')
.validate();
9. 验证的测试
test('验证邮箱格式', () {
expect(validateEmail(''), isNotNull);
expect(validateEmail('invalid'), isNotNull);
expect(validateEmail('test@example.com'), isNull);
});
test('验证密码强度', () {
expect(validatePassword('123'), isNotNull); // 太弱
expect(validatePassword('Abc123!@'), isNull); // 强
});
10. 验证的错误恢复
void _submitForm() {
final errors = validateAllFields();
if (hasErrors(errors)) {
_showErrorDialog(errors);
// 自动聚焦到第一个错误字段
_focusFirstErrorField(errors);
} else {
_submitToServer();
}
}
通过这些企业级验证技巧,你可以构建出生产级别的表单系统。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)