Flutter&OpenHarmony商城App表单验证组件开发
本文介绍了在Flutter和OpenHarmony平台上开发表单验证组件的关键技术。主要内容包括:1) 定义可复用的验证规则(必填、长度限制、格式验证等);2) 实现验证器组合功能,支持多规则验证;3) 构建带验证功能的输入框组件,包含错误提示和交互状态管理。通过合理设计验证触发时机和错误反馈机制,可提升表单的易用性和数据准确性。
前言
表单验证是商城应用中确保用户输入数据有效性的重要功能,广泛应用于登录注册、地址填写、支付信息等场景。一个设计良好的表单验证组件需要提供实时的输入反馈、清晰的错误提示,并支持多种验证规则。本文将详细介绍如何在Flutter和OpenHarmony平台上开发表单验证组件。
表单验证的设计需要考虑用户体验和数据安全。验证应该在合适的时机触发,既不能过于频繁打扰用户,也不能等到提交时才发现错误。错误提示应该明确告知用户问题所在和如何修正。
Flutter表单验证基础
首先定义验证规则:
typedef Validator = String? Function(String? value);
class Validators {
static Validator required({String? message}) {
return (value) {
if (value == null || value.trim().isEmpty) {
return message ?? '此项不能为空';
}
return null;
};
}
static Validator minLength(int length, {String? message}) {
return (value) {
if (value != null && value.length < length) {
return message ?? '至少输入$length个字符';
}
return null;
};
}
static Validator maxLength(int length, {String? message}) {
return (value) {
if (value != null && value.length > length) {
return message ?? '最多输入$length个字符';
}
return null;
};
}
}
Validators类提供了常用的验证规则工厂方法。每个方法返回一个Validator函数,接收输入值并返回错误信息或null。required验证非空,minLength和maxLength验证长度范围。message参数允许自定义错误提示。这种设计使验证规则可以灵活组合。
更多验证规则:
static Validator phone({String? message}) {
return (value) {
if (value == null || value.isEmpty) return null;
final regex = RegExp(r'^1[3-9]\d{9}$');
if (!regex.hasMatch(value)) {
return message ?? '请输入正确的手机号';
}
return null;
};
}
static Validator email({String? message}) {
return (value) {
if (value == null || value.isEmpty) return null;
final regex = RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$');
if (!regex.hasMatch(value)) {
return message ?? '请输入正确的邮箱地址';
}
return null;
};
}
static Validator pattern(RegExp regex, {String? message}) {
return (value) {
if (value == null || value.isEmpty) return null;
if (!regex.hasMatch(value)) {
return message ?? '格式不正确';
}
return null;
};
}
phone验证中国大陆手机号格式,email验证邮箱格式,pattern支持自定义正则表达式。当输入为空时返回null,让required规则处理空值验证。这种设计使验证规则可以独立使用或组合使用。
组合验证器
static Validator compose(List<Validator> validators) {
return (value) {
for (final validator in validators) {
final error = validator(value);
if (error != null) {
return error;
}
}
return null;
};
}
compose方法将多个验证规则组合成一个。按顺序执行验证,遇到第一个错误就返回。这种设计让开发者可以为一个输入框设置多个验证规则,如同时验证非空和格式。
验证输入框组件
class ValidatedTextField extends StatefulWidget {
final String? label;
final String? hintText;
final Validator? validator;
final TextEditingController? controller;
final bool obscureText;
final TextInputType? keyboardType;
final ValueChanged<String>? onChanged;
const ValidatedTextField({
Key? key,
this.label,
this.hintText,
this.validator,
this.controller,
this.obscureText = false,
this.keyboardType,
this.onChanged,
}) : super(key: key);
State<ValidatedTextField> createState() => _ValidatedTextFieldState();
}
class _ValidatedTextFieldState extends State<ValidatedTextField> {
String? _errorText;
bool _hasInteracted = false;
void _validate(String? value) {
if (!_hasInteracted) return;
setState(() {
_errorText = widget.validator?.call(value);
});
}
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (widget.label != null) ...[
Text(
widget.label!,
style: const TextStyle(
fontSize: 14,
color: Color(0xFF333333),
),
),
const SizedBox(height: 8),
],
_buildTextField(),
if (_errorText != null) ...[
const SizedBox(height: 4),
_buildErrorText(),
],
],
);
}
}
ValidatedTextField组件封装了带验证功能的输入框。_hasInteracted标记用户是否已经与输入框交互,避免初始状态就显示错误。_validate方法执行验证并更新错误状态。Column垂直排列标签、输入框和错误提示。条件渲染确保只在有错误时显示错误文字。
输入框构建:
Widget _buildTextField() {
return TextField(
controller: widget.controller,
obscureText: widget.obscureText,
keyboardType: widget.keyboardType,
decoration: InputDecoration(
hintText: widget.hintText,
hintStyle: const TextStyle(
fontSize: 14,
color: Color(0xFFCCCCCC),
),
contentPadding: const EdgeInsets.all(12),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(
color: _errorText != null
? const Color(0xFFE53935)
: const Color(0xFFEEEEEE),
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(
color: _errorText != null
? const Color(0xFFE53935)
: const Color(0xFFE53935),
),
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: const BorderSide(color: Color(0xFFE53935)),
),
),
onChanged: (value) {
_hasInteracted = true;
_validate(value);
widget.onChanged?.call(value);
},
onTap: () {
_hasInteracted = true;
},
);
}
Widget _buildErrorText() {
return Row(
children: [
const Icon(
Icons.error_outline,
size: 14,
color: Color(0xFFE53935),
),
const SizedBox(width: 4),
Text(
_errorText!,
style: const TextStyle(
fontSize: 12,
color: Color(0xFFE53935),
),
),
],
);
}
输入框边框颜色根据错误状态变化,有错误时显示红色边框。onChanged在输入变化时触发验证,onTap在点击时标记已交互。错误提示使用红色图标和文字,Row水平排列使提示更加醒目。这种设计提供了清晰的实时验证反馈。
OpenHarmony表单验证实现
@Component
struct ValidatedTextField {
@State errorText: string = ''
@State hasInteracted: boolean = false
@Prop label: string = ''
@Prop hintText: string = ''
@Prop value: string = ''
private validator: (value: string) => string = () => ''
private onChanged: (value: string) => void = () => {}
build() {
Column() {
if (this.label) {
Text(this.label)
.fontSize(14)
.fontColor('#333333')
.margin({ bottom: 8 })
}
this.InputField()
if (this.errorText) {
this.ErrorText()
}
}
.width('100%')
.alignItems(HorizontalAlign.Start)
}
validate(value: string) {
if (!this.hasInteracted) return
this.errorText = this.validator(value)
}
}
OpenHarmony的验证输入框使用@State管理错误状态和交互状态。@Prop接收标签、提示文字和当前值。validator是验证函数,onChanged是值变化回调。Column垂直排列标签、输入框和错误提示。条件渲染在有错误时显示错误文字。
输入框ArkUI实现:
@Builder
InputField() {
TextInput({ placeholder: this.hintText, text: this.value })
.width('100%')
.height(44)
.padding({ left: 12, right: 12 })
.borderRadius(8)
.border({
width: 1,
color: this.errorText ? '#E53935' : '#EEEEEE'
})
.placeholderColor('#CCCCCC')
.onChange((value: string) => {
this.hasInteracted = true
this.validate(value)
this.onChanged(value)
})
.onFocus(() => {
this.hasInteracted = true
})
}
@Builder
ErrorText() {
Row() {
Image($r('app.media.error'))
.width(14)
.height(14)
Text(this.errorText)
.fontSize(12)
.fontColor('#E53935')
.margin({ left: 4 })
}
.margin({ top: 4 })
}
TextInput组件创建输入框,border颜色根据错误状态变化。onChange在输入变化时触发验证,onFocus在获得焦点时标记已交互。ErrorText使用Row水平排列错误图标和文字。这种实现方式与Flutter版本功能一致。
表单组件
class ValidatedForm extends StatefulWidget {
final List<Widget> children;
final VoidCallback? onSubmit;
const ValidatedForm({
Key? key,
required this.children,
this.onSubmit,
}) : super(key: key);
State<ValidatedForm> createState() => ValidatedFormState();
}
class ValidatedFormState extends State<ValidatedForm> {
final _formKey = GlobalKey<FormState>();
bool validate() {
return _formKey.currentState?.validate() ?? false;
}
void submit() {
if (validate()) {
widget.onSubmit?.call();
}
}
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Column(
children: widget.children,
),
);
}
}
ValidatedForm组件封装了Flutter的Form组件,提供统一的验证和提交功能。_formKey用于访问Form的状态。validate方法触发所有子输入框的验证,submit方法在验证通过后执行提交回调。这种设计使表单的验证和提交更加便捷。
表单使用示例
class LoginForm extends StatefulWidget {
State<LoginForm> createState() => _LoginFormState();
}
class _LoginFormState extends State<LoginForm> {
final _formKey = GlobalKey<ValidatedFormState>();
final _phoneController = TextEditingController();
final _passwordController = TextEditingController();
Widget build(BuildContext context) {
return ValidatedForm(
key: _formKey,
children: [
ValidatedTextField(
label: '手机号',
hintText: '请输入手机号',
controller: _phoneController,
keyboardType: TextInputType.phone,
validator: Validators.compose([
Validators.required(message: '请输入手机号'),
Validators.phone(),
]),
),
const SizedBox(height: 16),
ValidatedTextField(
label: '密码',
hintText: '请输入密码',
controller: _passwordController,
obscureText: true,
validator: Validators.compose([
Validators.required(message: '请输入密码'),
Validators.minLength(6, message: '密码至少6位'),
]),
),
const SizedBox(height: 24),
ElevatedButton(
onPressed: () => _formKey.currentState?.submit(),
child: const Text('登录'),
),
],
onSubmit: _handleLogin,
);
}
void _handleLogin() {
// 执行登录逻辑
}
}
登录表单使用ValidatedForm包裹两个ValidatedTextField。手机号输入框使用required和phone组合验证,密码输入框使用required和minLength组合验证。点击登录按钮时调用表单的submit方法,验证通过后执行登录逻辑。这种使用方式简洁直观。
总结
本文详细介绍了Flutter和OpenHarmony平台上表单验证组件的开发过程。表单验证作为确保数据有效性的重要功能,其设计质量直接影响用户的填写体验和数据质量。通过验证规则、验证输入框、表单组件等的合理设计,我们为用户提供了清晰的实时验证反馈。在实际项目中,还可以进一步添加异步验证、表单状态管理等功能。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
更多推荐

所有评论(0)