Flutter表单验证插件ez_validator的使用

发布于 1周前 作者 itying888 来自 Flutter

Flutter表单验证插件ez_validator的使用

EzValidator简介

EzValidator 是一个为Flutter量身定制的数据验证库,它提供了简单易用的API来定义和执行数据验证规则。它受到Yup的启发,简化了在Flutter应用中定义和强制执行数据模式的过程。

关键特性

  • Flutter Schema Builder: 无缝集成到Flutter项目中,构建和管理数据验证模式。
  • 多样的验证功能: 支持字段验证和对象验证,满足不同的验证需求。

安装

pubspec.yaml文件中添加依赖:

dependencies:
  ez_validator: any # 或者指定最新版本

使用示例

定义Schema

创建一个包含电子邮件、密码和日期字段的用户数据验证模式:

final EzSchema userSchema = EzSchema.shape(
  {
    "email": EzValidator<String>(label: "Email").required().email(),
    "password": EzValidator<String>(label: 'Password').required().minLength(8),
    'date': EzValidator<DateTime>()
        .required()
        .date()
        .minDate(DateTime(2019))
        .maxDate(DateTime(2025)),
  },
);

验证数据

使用catchErrors方法验证数据对象:

final errors = userSchema.catchErrors({
  'email': 'example@domain.com',
  'password': '12345678',
  'date': DateTime.now(),
});

print(errors);

如果数据有效,errors将是一个空映射;否则,它将包含字段名及其对应的错误消息。

使用validateSync方法

同时获取处理后的数据和验证错误:

final (data, errors) = userSchema.validateSync({
  'email': 'example@domain.com',
  'password': '12345678',
  'date': DateTime.now(),
});

print(data);   // 处理后的数据
print(errors); // 验证错误

自定义验证规则

使用addMethod函数添加自定义验证逻辑:

final checkJson = EzValidator<Map<String, dynamic>>()
    .addMethod((v) => v?['foo'] == 'bar' ? null : 'Foo should be bar')
    .addMethod((v) => v?['bar'] == 'Flutter' ? null : 'Bar should be Flutter')
    .addMethod((v) => v?['items'][0] == 'a' ? null : 'First item should be a')
    .build();

final errors = checkJson({
  'foo': 'bar',
  'bar': 'Flutter',
  'items': ['a', 'b', 'c']
});

print(errors); // 输出验证错误,如果有

在Flutter Widget中直接使用

例如,在TextFormField中进行电子邮件验证:

TextFormField(
  validator: EzValidator<String>()
      .required()
      .email()
      .build(),
  decoration: InputDecoration(labelText: 'Email'),
),

示例应用

以下是一个完整的示例应用,展示了如何在Flutter中使用EzValidator进行表单验证:

import 'dart:io';
import 'package:ez_validator/ez_validator.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'EzValidator Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'EzValidator Example'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, this.title}) : super(key: key);

  final String? title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  Map<String, dynamic> form = {"number": '5', "pos": '-5', 'file': File('')};
  Map<dynamic, dynamic> errors = {};

  EzSchema formSchema = EzSchema.shape(
    {
      "email": EzValidator<String>(label: "l'email").required().email(),
      "password":
          EzValidator<String>(label: 'le mot de passe').required().minLength(8),
      "age": EzValidator<num>(label: 'l\'age').required().number().max(18),
      "birth_year": EzValidator<int>().required().number().min(2017),
      "file": EzValidator<File>().required().addMethod((file) =>
          file != null &&
          file
              .lastAccessedSync()
              .isAfter(DateTime.now().subtract(const Duration(days: 1)))),
      "date":
          EzValidator<DateTime>(defaultValue: DateTime(2018)).required().date(),
    },
  );

  void validate() {
    try {
      final res = formSchema.validateSync(form);
      setState(() {
        errors = res.$2;
      });
      print(res.$1);
      errors.forEach((key, value) {
        print('$key ====> $value');
      });
    } catch (e) {
      print(e);
      Fluttertoast.showToast(
        msg: "Missing fields input",
        toastLength: Toast.LENGTH_SHORT,
        gravity: ToastGravity.BOTTOM,
        timeInSecForIosWeb: 1,
        backgroundColor: Colors.red,
        textColor: Colors.white,
        fontSize: 16.0,
      );
    }
  }

  InputDecoration _getInputDecoration(IconData icon, String label) {
    return InputDecoration(
      prefixIcon: Icon(icon),
      border: InputBorder.none,
      fillColor: const Color(0xfff3f3f4),
      filled: true,
      hintText: label,
    );
  }

  _onChange(String name, dynamic value) {
    form[name] = value;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title as String),
      ),
      body: Center(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Expanded(
              child: Container(
                color: Colors.black12,
                child: Padding(
                  padding: const EdgeInsets.symmetric(horizontal: 25.0),
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      TextField(
                        onChanged: (value) => _onChange('email', value),
                        decoration: _getInputDecoration(Icons.email, "Email"),
                      ),
                      if (errors.containsKey('email')) Text(errors['email']),
                      const SizedBox(height: 10.0),
                      TextField(
                        onChanged: (value) => _onChange('password', value),
                        decoration:
                            _getInputDecoration(Icons.password, "Password"),
                      ),
                      if (errors.containsKey('password')) Text(errors['password']),
                      const SizedBox(height: 10.0),
                      TextField(
                        keyboardType: TextInputType.number,
                        onChanged: (value) => _onChange('age', value),
                        decoration: _getInputDecoration(
                            Icons.supervised_user_circle_outlined, "Age"),
                      ),
                      if (errors.containsKey('age')) Text(errors['age']),
                      const SizedBox(height: 10.0),
                      TextField(
                        keyboardType: TextInputType.number,
                        onChanged: (value) =>
                            _onChange('birth_year', int.tryParse(value)),
                        decoration: _getInputDecoration(
                            Icons.date_range_outlined, "Birth Year"),
                      ),
                      if (errors.containsKey('birth_year')) Text(errors['birth_year']),
                      const SizedBox(height: 10.0),
                      MaterialButton(
                        onPressed: validate,
                        color: Colors.white,
                        highlightColor: Colors.red,
                        child: const Text("Submit"),
                      ),
                      MaterialButton(
                        onPressed: () {
                          EzValidator.setLocale(const FrLocale());
                        },
                        color: Colors.white,
                        highlightColor: Colors.red,
                        child: const Text("Fr Locale"),
                      )
                    ],
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

此示例展示了如何在Flutter应用中使用EzValidator进行表单验证,并在发生错误时显示相应的错误信息。


更多关于Flutter表单验证插件ez_validator的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter表单验证插件ez_validator的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter中使用ez_validator插件进行表单验证的代码示例。ez_validator是一个用于Flutter的表单验证库,它允许你轻松地对表单字段进行验证。

首先,确保在你的pubspec.yaml文件中添加ez_validator依赖:

dependencies:
  flutter:
    sdk: flutter
  ez_validator: ^x.y.z  # 替换为最新版本号

然后,运行flutter pub get来安装依赖。

接下来,下面是一个完整的示例,展示如何使用ez_validator进行表单验证:

import 'package:flutter/material.dart';
import 'package:ez_validator/ez_validator.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('ez_validator Example'),
        ),
        body: Padding(
          padding: const EdgeInsets.all(16.0),
          child: MyForm(),
        ),
      ),
    );
  }
}

class MyForm extends StatefulWidget {
  @override
  _MyFormState createState() => _MyFormState();
}

class _MyFormState extends State<MyForm> with ValidationMixin {
  final TextEditingController emailController = TextEditingController();
  final TextEditingController passwordController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[
        TextFormField(
          controller: emailController,
          decoration: InputDecoration(labelText: 'Email'),
          validator: (value) => validateEmail(value, errorMsg: 'Invalid email'),
        ),
        SizedBox(height: 16),
        TextFormField(
          controller: passwordController,
          decoration: InputDecoration(labelText: 'Password'),
          obscureText: true,
          validator: (value) => validateMinLength(value, minLength: 6, errorMsg: 'Password must be at least 6 characters'),
        ),
        SizedBox(height: 24),
        ElevatedButton(
          onPressed: () async {
            final isValid = await validateAllFields();
            if (isValid) {
              // 处理表单提交
              print('Form submitted successfully');
            } else {
              // 显示错误信息
              print('Validation failed');
            }
          },
          child: Text('Submit'),
        ),
      ],
    );
  }

  @override
  void dispose() {
    emailController.dispose();
    passwordController.dispose();
    super.dispose();
  }
}

// 自定义验证器(可选)
String? validateEmail(String? value, {String? errorMsg}) {
  final emailRegex = RegExp(
    r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-\.]+\.[a-zA-Z]{2,}$"
  );
  if (value == null || !emailRegex.hasMatch(value)) {
    return errorMsg;
  }
  return null;
}

关键点解释

  1. 依赖添加:在pubspec.yaml中添加ez_validator依赖。
  2. ValidationMixin:通过with ValidationMixin将验证功能混入到State类中。
  3. TextFormField:每个TextFormField都设置了一个validator,这些验证器通过ez_validator提供的内置函数(如validateEmailvalidateMinLength)或自定义函数(如示例中的validateEmail)来实现。
  4. validateAllFields:使用validateAllFields()方法异步验证所有字段,如果所有字段都有效,则继续处理表单提交;否则,显示错误信息。

请注意,示例中的validateEmail是一个自定义验证器,用于验证电子邮件格式。ez_validator也提供了一些内置的验证器,你可以根据需要进行选择和使用。

回到顶部