Flutter功能验证插件valida的使用
Flutter功能验证插件valida的使用
valida
是一个用于Dart和Flutter的验证库,允许通过代码注解创建字段、参数和对象的验证器。以下是关于如何使用 valida
插件的完整示例demo。
1. 添加依赖
首先,在 pubspec.yaml
文件中添加 valida
和相关生成器的依赖:
dependencies:
valida: ^0.0.1
dev_dependencies:
build_runner: <latest>
valida_generator: ^0.0.1
然后运行 pub get
来安装依赖:
dart pub get
2. 创建模型类
接下来,创建一个模型类并使用 valida
注解来定义验证规则。以下是一个示例模型类 FormTest
:
import 'package:valida/valida.dart';
part 'model.g.dart';
@Valida(nullableErrorLists: true, customValidate: FormTest._customValidate)
class FormTest {
static List<ValidaError> _customValidate(Object? value) {
return [];
}
@ValidaString(
minLength: 15,
maxLength: 50,
matches: r'^[a-zA-Z]+$',
customValidate: _customValidateStr,
description: '应包含15到50个字符,仅限字母且不能是 "WrongValue"',
)
final String longStr;
@ValidaString(maxLength: 20, contains: '@')
final String shortStr;
@ValidaNum(isInt: true, min: 0, customValidate: _customValidateNum)
final num positiveInt;
static List<ValidaError> _customValidateNum(num value) {
return [];
}
@ValidaFunction()
static List<ValidaError> _customValidate2(FormTest value) {
return [
if (value.optionalDecimal == null && value.identifier == null)
ValidaError(
errorCode: 'CustomError.not',
message: '自定义错误消息',
property: 'identifier',
value: value,
)
];
}
@ValidaFunction()
List<ValidaError> _customValidate3() {
return _customValidate2(this);
}
@ValidaNum(
min: 0,
max: 1,
comp: ValidaComparison<num>(
less: CompVal(0),
moreEq: CompVal.list([CompVal.ref('positiveInt')]),
),
)
final double? optionalDecimal;
@ValidaList(minLength: 1, each: ValidaString(isDate: true, maxLength: 3))
final List<String> nonEmptyList;
@ValidaString(isUUID: UUIDVersion.v4)
final String? identifier;
final NestedField? nested;
const FormTest({
required this.longStr,
required this.shortStr,
required this.positiveInt,
required this.optionalDecimal,
required this.nonEmptyList,
required this.identifier,
this.nested,
});
}
List<ValidaError> _customValidateStr(String value) {
// 验证 `value` 并返回错误列表
return [
if (value == 'WrongValue')
ValidaError(
errorCode: 'CustomError.wrong',
message: '不允许使用 "WrongValue"',
property: 'longStr',
value: value,
),
];
}
@Valida()
class NestedField {
@ValidaString(isTime: true)
final String timeStr;
@ValidaDate(min: '2021-01-01')
final DateTime dateWith2021Min;
@ValidaDate(max: 'now')
final DateTime? optionalDateWithNowMax;
NestedField({
required this.timeStr,
required this.dateWith2021Min,
required this.optionalDateWithNowMax,
});
}
3. 生成验证代码
使用 build_runner
来生成验证代码:
dart pub run build_runner watch --delete-conflicting-outputs
这将生成一个名为 model.g.dart
的文件,其中包含验证逻辑。
4. 使用生成的验证函数
在 main.dart
中使用生成的验证函数 validateFormTest
来验证 FormTest
对象:
import 'model.dart';
void main() {
const form = FormTest(
longStr: 'long Str',
shortStr: 'shortStr',
positiveInt: 2.4,
optionalDecimal: 3,
nonEmptyList: [],
identifier: 'identifier',
);
final FormTestValidation validation = validateFormTest(form);
assert(validation is Validation<FormTest, FormTestField>);
print('Number of errors: ${validation.numErrors}');
print('Has errors: ${validation.hasErrors}');
final errorsMap = validation.errorsMap;
print('Errors map: $errorsMap');
// 检查具体字段的错误
if (errorsMap.isNotEmpty) {
errorsMap.forEach((field, errors) {
print('Field: $field, Errors: ${errors.map((e) => e.message)}');
});
}
}
5. 生成的验证代码
build_runner
生成的验证代码会包括以下几个部分:
- 一个函数
ModelValidation validateModel(Model)
,用于执行验证。 ModelValidation
类,继承自Validation<Model, ModelField>
,包含错误数量、验证值、是否成功等实用属性。- 一个枚举
ModelField
,表示被验证类的字段。 - 一个实用类
ModelValidationFields
,包含每个字段的错误列表。
以下是生成的 FormTestValidation
类的部分代码:
enum FormTestField {
longStr,
shortStr,
positiveInt,
optionalDecimal,
nonEmptyList,
identifier,
nested,
global,
}
class FormTestValidationFields {
const FormTestValidationFields(this.errorsMap);
final Map<FormTestField, List<ValidaError>> errorsMap;
NestedFieldValidation? get nested {
final l = errorsMap[FormTestField.nested];
return (l != null && l.isNotEmpty)
? l.first.nestedValidation as NestedFieldValidation?
: null;
}
List<ValidaError>? get longStr => errorsMap[FormTestField.longStr];
List<ValidaError>? get shortStr => errorsMap[FormTestField.shortStr];
List<ValidaError>? get positiveInt => errorsMap[FormTestField.positiveInt];
List<ValidaError>? get optionalDecimal =>
errorsMap[FormTestField.optionalDecimal];
List<ValidaError>? get nonEmptyList => errorsMap[FormTestField.nonEmptyList];
List<ValidaError>? get identifier => errorsMap[FormTestField.identifier];
}
class FormTestValidation extends Validation<FormTest, FormTestField> {
FormTestValidation(this.errorsMap, this.value, this.fields)
: super(errorsMap);
final Map<FormTestField, List<ValidaError>> errorsMap;
final FormTest value;
final FormTestValidationFields fields;
}
FormTestValidation validateFormTest(FormTest value) {
final errors = <FormTestField, List<ValidaError>>{};
final _nestedValidation = value.nested == null
? null
: validateNestedField(value.nested!).toError(property: 'nested');
errors[FormTestField.nested] = [
if (_nestedValidation != null) _nestedValidation
];
errors[FormTestField.global] = [
...FormTest._customValidate2(value),
...value._customValidate3()
];
errors[FormTestField.longStr] = [
..._customValidateStr(value.longStr),
if (value.longStr.length < 15)
ValidaError(
message: r'长度应至少为15',
errorCode: 'ValidaString.minLength',
property: 'longStr',
validationParam: 15,
value: value.longStr,
),
if (value.longStr.length > 50)
ValidaError(
message: r'长度应不超过50',
errorCode: 'ValidaString.maxLength',
property: 'longStr',
validationParam: 50,
value: value.longStr,
),
if (!RegExp(r"^[a-zA-Z]+$").hasMatch(value.longStr))
ValidaError(
message: r'应匹配 ^[a-zA-Z]+$',
errorCode: 'ValidaString.matches',
property: 'longStr',
validationParam: RegExp(r"^[a-zA-Z]+$"),
value: value.longStr,
)
];
// ...
// 更多验证逻辑
// ...
errors[FormTestField.nonEmptyList] = [
if (value.nonEmptyList.length < 1)
ValidaError(
message: r'长度应至少为1',
errorCode: 'ValidaList.minLength',
property: 'nonEmptyList',
validationParam: 1,
value: value.nonEmptyList,
)
];
errors.removeWhere((k, v) => v.isEmpty);
return FormTestValidation(
errors,
value,
FormTestValidationFields(errors),
);
}
更多关于Flutter功能验证插件valida的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter功能验证插件valida的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter开发中,validator
通常是用于表单验证的一种机制,而不是一个特定的插件名称。不过,假设你提到的 valida
是一个用于表单验证的Flutter插件(注意:实际中并不存在一个广泛认知的名为 valida
的Flutter插件,这里我将以一个假设的表单验证插件为例进行说明),我们可以模拟一个类似的表单验证插件的使用方式。
为了演示表单验证,我将使用Flutter的内置功能结合一些假设的验证逻辑来展示如何实现表单验证。在实际应用中,你可能需要使用一个具体的第三方验证插件,但原理是相似的。
示例代码
以下是一个简单的Flutter应用示例,它演示了如何使用自定义验证逻辑来验证表单输入:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Form Validation Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyFormPage(),
);
}
}
class MyFormPage extends StatefulWidget {
@override
_MyFormPageState createState() => _MyFormPageState();
}
class _MyFormPageState extends State<MyFormPage> {
final _formKey = GlobalKey<FormState>();
String _name = '';
String _email = '';
String _password = '';
// 自定义验证函数
String? validateName(String? value) {
if (value == null || value.isEmpty) {
return 'Name is required';
}
return null;
}
String? validateEmail(String? value) {
if (value == null || !value.contains('@')) {
return 'Please enter a valid email address';
}
return null;
}
String? validatePassword(String? value) {
if (value == null || value.length < 6) {
return 'Password must be at least 6 characters long';
}
return null;
}
void _submitForm() {
if (_formKey.currentState!.validate()) {
// 如果所有字段都通过验证
_formKey.currentState!.save();
print('Name: $_name');
print('Email: $_email');
print('Password: $_password');
// 这里可以添加提交表单的逻辑,比如发送数据到服务器
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Form Validation Example'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
TextFormField(
decoration: InputDecoration(labelText: 'Name'),
validator: validateName,
onSaved: (value) => _name = value!,
),
TextFormField(
decoration: InputDecoration(labelText: 'Email'),
validator: validateEmail,
onSaved: (value) => _email = value!,
),
TextFormField(
decoration: InputDecoration(labelText: 'Password'),
obscureText: true,
validator: validatePassword,
onSaved: (value) => _password = value!,
),
SizedBox(height: 20),
ElevatedButton(
onPressed: _submitForm,
child: Text('Submit'),
),
],
),
),
),
);
}
}
解释
- GlobalKey<FormState>:用于访问Form的状态,以便在提交时验证表单。
- TextFormField:用于创建文本输入字段,每个字段都有一个
validator
函数,该函数在表单提交时被调用。 - validator函数:每个验证函数都接受一个可能的空字符串值,并返回一个错误消息(如果输入无效)或
null
(如果输入有效)。 - onSaved回调:当表单验证通过并且用户提交表单时,这些回调用于保存字段的值。
- _submitForm方法:首先调用
_formKey.currentState!.validate()
来验证所有字段,如果验证通过,则调用_formKey.currentState!.save()
来保存字段值,并执行提交逻辑。
这个例子展示了如何使用Flutter的内置功能来实现表单验证,而不是依赖于特定的第三方插件。如果你确实需要使用一个特定的验证插件(假设名为valida
),你应该查阅该插件的文档来了解如何集成和使用它。通常,第三方插件会提供更高级或更便捷的验证功能,但基本原理是相似的。