Flutter数据验证插件zod_validation的使用

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

Flutter数据验证插件zod_validation的使用

zod_validation 是一个用于Flutter和Shelf项目的强大数据验证库。它提供了丰富的验证方法,并且支持多语言国际化。

使用方法

在Flutter中使用

在Flutter中,你可以将 zod_validationTextFormField 结合使用,进行表单验证。

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

void main() => runApp(MyApp());

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

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

class _MyFormState extends State<MyForm> {
  final _formKey = GlobalKey<FormState>();

  @override
  Widget build(BuildContext context) {
    return Form(
      key: _formKey,
      child: Column(
        children: <Widget>[
          TextFormField(
            validator: Zod().required().min(3).email().build,
            decoration: InputDecoration(labelText: 'Email'),
          ),
          TextFormField(
            validator: Zod().required().min(6).build,
            decoration: InputDecoration(labelText: 'Password'),
          ),
          ElevatedButton(
            onPressed: () {
              if (_formKey.currentState!.validate()) {
                // 如果验证通过,执行提交操作
                ScaffoldMessenger.of(context).showSnackBar(
                  SnackBar(content: Text('Processing Data')),
                );
              }
            },
            child: Text('Submit'),
          ),
        ],
      ),
    );
  }
}

所有验证方法

zod_validation 提供了多种验证方法,包括但不限于:

  • password
  • email
  • isEmails
  • min
  • max
  • equals
  • type<T>
  • required
  • cpf
  • cnpj
  • cpfCnpj
  • isDate
  • optional
  • custom

在Shelf中使用

在Shelf项目中,你可以使用 zod_validation 来验证API请求参数。

import 'package:shelf/shelf.dart';
import 'package:shelf_router/shelf_router.dart' as shelf_router;
import 'package:json_annotation/json_annotation.dart';
import 'package:zod_validation/zod_validation.dart';
import 'dart:convert';

@shelf_router.Route.post('/register')
Future<Response> register(Request req) async {
  final data = jsonDecode(await req.readAsString());

  final requiredParams = {
    'email': Zod().email(),
    'password': Zod().password(),
    'data': {
      'user_name': Zod().min(8).max(20),
      'platform': Zod().type<String>(),
    },
  };

  final zod = Zod.validate(data: data, params: requiredParams);
  if (zod.isNotValid) {
    return Response(400, body: jsonEncode({
      'message': 'invalid params',
      'params': zod.result
    }));
  }

  // zod.result 是一个包含无效参数键和消息的Map
  // 例如:
  // {
  //    'data': {
  //      'user_name': 'At least 8 characters'
  //    }
  // }

  // 处理有效数据
  return Response.ok(jsonEncode({'message': 'User registered successfully'}));
}

更改语言

你可以轻松地更改验证消息的语言。

// 单个验证器
Zod(localeZod: LocaleEN()).required().build,

// 应用于整个系统
Zod.zodLocaleInstance = LocaleEN();

创建自定义语言

你还可以创建自己的语言包。

class MyLocale implements ILocaleZod {
  // 实现 ILocaleZod 中所需的方法
}

Zod(localeZod: MyLocale()).required().build

示例代码

以下是一个完整的示例,展示了如何在Flutter项目中使用 zod_validation 进行数据验证。

import 'package:zod_validation/zod_validation.dart';

void main() {
  final params = {
    'user': {
      'platform': Zod().required(),
      'data': {
        'id': Zod().type<int>(),
        'name': Zod().min(3).max(10),
        'email': Zod().email(),
        'phone': Zod().optional(isValidWhenEmpty: false).phone(),
      },
    }
  };

  /// 接收到的请求参数
  final requestParams = <String, dynamic>{
    'user': {
      'platform': 'web',
      'data': {
        'id': 1,
        'name': 'John Doe',
        'email': 'welito@gmail.com',
        'phone': '',
      }
    }
  };

  final result = Zod.validate(params: params, data: requestParams);
  if (result.isNotValid) {
    print(result.result);
  } else {
    print('Valid');
  }
}

希望这些信息对你有所帮助!如果你有任何问题或需要进一步的帮助,请随时联系我。


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

1 回复

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


当然,下面是一个关于如何在Flutter中使用zod_validation插件进行数据验证的代码示例。zod_validation是一个受Zod启发的Dart数据验证库,尽管Flutter社区中可能直接以zod_validation命名的库不常见,但我们可以使用类似逻辑的数据验证库或自行实现类似功能。这里,为了演示目的,我将展示一个类似Zod验证风格的自定义实现。

首先,确保你的pubspec.yaml文件中添加了必要的依赖项,比如json_annotation用于JSON序列化和反序列化(如果数据来自JSON)。

dependencies:
  flutter:
    sdk: flutter
  json_annotation: ^4.3.0

然后,创建一个数据模型和验证逻辑。假设我们有一个用户注册表单,需要验证用户名、电子邮件和密码。

数据模型

import 'package:json_annotation/json_annotation.dart';

part 'user_model.g.dart';

@JsonSerializable()
class User {
  final String username;
  final String email;
  final String password;

  User({required this.username, required this.email, required this.password});

  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
  Map<String, dynamic> toJson() => _$UserToJson(this);
}

运行flutter pub run build_runner build生成user_model.g.dart文件。

验证逻辑

创建一个验证类,模仿Zod的风格:

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

class UserValidator {
  static Map<String, String?> validateUser(User user) {
    final Map<String, String?> errors = {};

    if (user.username == null || user.username!.isEmpty || user.username!.length < 3) {
      errors['username'] = 'Username must be at least 3 characters long.';
    }

    final RegExp emailRegex = RegExp(
        r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$");
    if (!emailRegex.hasMatch(user.email!)) {
      errors['email'] = 'Email is not valid.';
    }

    if (user.password == null || user.password!.length < 6) {
      errors['password'] = 'Password must be at least 6 characters long.';
    }

    return errors;
  }
}

使用验证逻辑

在一个Flutter表单中使用这个验证逻辑:

import 'package:flutter/material.dart';
import 'user_model.dart';
import 'user_validator.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('User Registration'),
        ),
        body: RegistrationForm(),
      ),
    );
  }
}

class RegistrationForm extends StatefulWidget {
  @override
  _RegistrationFormState createState() => _RegistrationFormState();
}

class _RegistrationFormState extends State<RegistrationForm> {
  final _formKey = GlobalKey<FormState>();
  late String _username;
  late String _email;
  late String _password;

  @override
  Widget build(BuildContext context) {
    return Form(
      key: _formKey,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          TextFormField(
            decoration: InputDecoration(labelText: 'Username'),
            validator: (value) {
              if (value == null || value.isEmpty || value.length < 3) {
                return 'Username must be at least 3 characters long.';
              }
              return null;
            },
            onSaved: (value) => _username = value!,
          ),
          TextFormField(
            decoration: InputDecoration(labelText: 'Email'),
            validator: (value) {
              final RegExp emailRegex = RegExp(
                  r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$");
              if (!emailRegex.hasMatch(value!)) {
                return 'Email is not valid.';
              }
              return null;
            },
            onSaved: (value) => _email = value!,
          ),
          TextFormField(
            decoration: InputDecoration(labelText: 'Password'),
            obscureText: true,
            validator: (value) {
              if (value == null || value.length < 6) {
                return 'Password must be at least 6 characters long.';
              }
              return null;
            },
            onSaved: (value) => _password = value!,
          ),
          SizedBox(height: 20),
          ElevatedButton(
            onPressed: () async {
              if (_formKey.currentState!.validate()) {
                _formKey.currentState!.save();
                final User user = User(
                  username: _username,
                  email: _email,
                  password: _password,
                );
                final Map<String, String?> errors = UserValidator.validateUser(user);

                if (errors.isNotEmpty) {
                  // 显示错误信息,这里可以使用SnackBar或其他UI组件
                  ScaffoldMessenger.of(context).showSnackBar(
                    SnackBar(
                      content: Text('Validation errors found. Please check the form.'),
                    ),
                  );
                } else {
                  // 成功提交数据
                  print('User data is valid: $user');
                }
              }
            },
            child: Text('Register'),
          ),
        ],
      ),
    );
  }
}

在这个例子中,我们直接在TextFormFieldvalidator属性中实现了部分验证逻辑,以展示Flutter内置的表单验证功能。然后,在按钮点击事件中,我们再次调用UserValidator.validateUser方法进行更复杂的验证,这模拟了Zod风格的集中验证逻辑。

请注意,实际应用中你可能会希望将验证逻辑进一步抽象或复用,并根据需要调整UI反馈机制。

回到顶部