Flutter代码生成:告别重复劳动,效率飙升

Flutter 中的自动生成代码是一个非常重要且能极大提升开发效率的特性。它主要通过 代码生成(Code Generation) 来实现,核心是利用 Dart 的 build_runner 工具和 注解(Annotation)。

最常用的场景包括:

  1. JSON 序列化与反序列化:将 JSON 数据自动转换为 Dart 模型类(Model Class),以及将模型类转换为 JSON。
  2. 路由生成:为命名路由自动生成路径名称和参数传递代码。
  3. 依赖注入:自动生成依赖注册和获取的代码。
  4. 生成数据类:自动生成不可变的数据类(Data Class),包含 copyWith、toString、equals 等方法。

下面我将重点介绍最常用的 JSON 序列化 和 路由生成。


  1. JSON 序列化 - json_serializable

手动编写 fromJson 和 toJson 方法非常繁琐且容易出错,json_serializable 包可以自动生成这些代码。

步骤一:添加依赖

在 pubspec.yaml 文件中添加以下依赖:

yaml 复制代码
dependencies:
  flutter:
    sdk: flutter
  json_annotation: ^4.8.1 # 最新版本请查阅 pub.dev

dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_lints: ^2.0.0
  build_runner: ^2.4.4 # 用于运行代码生成器
  json_serializable: ^6.7.1 # 最新版本请查阅 pub.dev

运行 flutter pub get 获取依赖。

步骤二:创建模型类并使用注解

创建一个简单的用户模型类 user.dart:

dart 复制代码
import 'package:json_annotation/json_annotation.dart';

// 这个文件会自动生成,第一次运行前会报错,属于正常现象
part 'user.g.dart';

// 告诉生成器这个类需要生成序列化代码
@JsonSerializable()
class User {
  final String name;
  final String email;
  final int? age; // 可空字段

  User({required this.name, required this.email, this.age});

  // 从JSON映射创建User实例的工厂方法
  // 生成的代码在 _$UserFromJson 中
  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);

  // 将User实例转换为JSON映射
  // 生成的代码在 _$UserToJson 中
  Map<String, dynamic> toJson() => _$UserToJson(this);
}

步骤三:运行代码生成器

在项目根目录下打开终端,运行以下命令:

一次性生成:

bash 复制代码
flutter pub run build_runner build

这条命令会生成 user.g.dart 文件,之后你就可以正常使用 User.fromJson 和 toJson 方法了。

持续监听文件变化并自动生成(推荐在开发时使用):

bash 复制代码
flutter pub run build_runner watch

使用 watch 后,当你修改了 User 类(比如增加一个字段),保存文件后生成器会自动重新生成 .g.dart 文件,非常方便。

如果之前生成过,需要重新生成(遇到奇怪问题时使用):

bash 复制代码
flutter pub run build_runner build --delete-conflicting-outputs

--delete-conflicting-outputs 参数会强制删除之前生成的文件并重新生成,解决大部分冲突问题。

最终生成的文件 (user.g.dart):

这个文件是自动生成的,不要手动编辑它。

dart 复制代码
// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'user.dart';

// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************

User _$UserFromJson(Map<String, dynamic> json) => User(
      name: json['name'] as String,
      email: json['email'] as String,
      age: json['age'] as int?,
    );

Map<String, dynamic> _$UserToJson(User instance) => <String, dynamic>{
      'name': instance.name,
      'email': instance.email,
      'age': instance.age,
    };

  1. 路由生成 - go_router 或 auto_route

对于大型项目,管理命名路由是一个挑战。这两个包可以帮你自动生成路由相关的代码。

这里以功能强大且流行的 go_router (官方推荐) 为例,它本身通过基于字符串的路由表工作,不需要代码生成,但能很好地管理路由。

如果你需要类型安全、参数自动注入等更高级的功能,可以看 auto_route。

使用 go_router (无需代码生成,但智能管理)

  1. 添加依赖:

    yaml 复制代码
    dependencies:
      go_router: ^11.0.0
  2. 配置路由:

    dart 复制代码
    import 'package:go_router/go_router.dart';
    
    final GoRouter router = GoRouter(
      routes: <RouteBase>[
        GoRoute(
          path: '/',
          builder: (BuildContext context, GoRouterState state) => const HomePage(),
        ),
        GoRoute(
          path: '/details/:id', // 使用参数 id
          builder: (BuildContext context, GoRouterState state) {
            // 从 state.params 中获取参数
            final String id = state.pathParameters['id']!;
            return DetailsPage(id: id);
          },
        ),
      ],
    );
    
    // 在 MaterialApp 中使用
    MaterialApp.router(
      routerConfig: router,
      ...
    )
  3. 导航:

    dart 复制代码
    // 跳转到详情页
    context.go('/details/123');

go_router 通过智能解析路径来自动处理参数,无需生成代码。

使用 auto_route (需要代码生成)

如果你更喜欢基于注解的、类型安全的路由,auto_route 是更好的选择。它的使用方式和 json_serializable 非常相似。

  1. 添加依赖 (pubspec.yaml):

    yaml 复制代码
    dependencies:
      auto_route: ^7.0.0
    dev_dependencies:
      build_runner: ^2.4.4
      auto_route_generator: ^7.0.0
  2. 使用注解创建路由 (router.dart):

    dart 复制代码
    import 'package:auto_route/auto_route.dart';
    import 'package:flutter/material.dart';
    
    part 'router.gr.dart'; // 将会生成的文件
    
    @AutoRouterConfig()
    class AppRouter extends $AppRouter {
      @override
      List<AutoRoute> get routes => [
            AutoRoute(page: HomeRoute.page, initial: true),
            AutoRoute(page: DetailsRoute.page),
          ];
    }
    
    @RoutePage()
    class HomePage extends StatelessWidget { ... }
    
    @RoutePage()
    class DetailsPage extends StatelessWidget {
      final String id;
      DetailsPage({required this.id});
    }
  3. 运行生成器:

    bash 复制代码
    flutter pub run build_runner watch

    它会生成 router.gr.dart 文件,其中包含了 HomeRoute、DetailsRoute 等类以及路径配置。

  4. 导航 (类型安全):

    dart 复制代码
    // 不再需要传递字符串路径
    context.pushRoute(DetailsRoute(id: '123'));

总结

场景 推荐包 命令 优点

JSON 序列化 json_serializable build_runner build 避免手写错误,节省时间

路由管理 go_router 无 官方推荐,配置简单,功能强大

类型安全路由 auto_route build_runner build 类型安全,参数自动注入

核心流程:

  1. 在 pubspec.yaml 中添加依赖(包括 build_runner 这样的开发依赖)。
  2. 在你的 Dart 代码中使用特定的注解(如 @JsonSerializable, @RoutePage)。
  3. 在终端运行 flutter pub run build_runner build 或 watch 命令。
  4. 使用生成的代码(.g.dart 或 .gr.dart 文件)。

学会使用代码生成可以让你从大量重复、易错的代码中解放出来,专注于业务逻辑,是 Flutter 开发者必备的技能。

相关推荐
liulian09167 小时前
Flutter for OpenHarmony 跨平台开发:单位转换功能实战指南
flutter
千码君20168 小时前
Trae:一些关于flutter和 go前后端开发构建的分享
android·flutter·gradle·android-studio·trae·vibe code
maaath9 小时前
【maaath】Flutter for OpenHarmony 手表配饰应用实战开发
flutter·华为·harmonyos
maaath10 小时前
【maaath】Flutter for OpenHarmony 跨平台计算器应用开发实践
flutter·华为·harmonyos
maaath15 小时前
【maaath】Flutter for OpenHarmony 闹钟时钟应用开发实战
flutter·华为·harmonyos
maaath15 小时前
【maaath】Flutter for OpenHarmony 短信管理应用实战
flutter·华为·harmonyos
maaath16 小时前
【maaath】Flutter for OpenHarmony打造跨平台便签备忘录应用
flutter·华为·harmonyos
千码君201616 小时前
flutter:与Android Studio模拟器的调试分享
android·flutter
xmdy586617 小时前
Flutter+开源鸿蒙实战|智联邻里Day8 Lottie动画集成+url_launcher跳转拨号+个人中心完善+全局UI统一
flutter·开源·harmonyos
liulian09161 天前
Flutter for OpenHarmony 跨平台开发:颜色选择器功能实战指南
flutter