flutter的freezed

freezed的作用

用于自动生成不可变数据类和联合类型(sealed unions)的代码生成库。

引入

sql 复制代码
flutter pub add freezed_annotation
flutter pub add --dev build_runner
flutter pub add --dev freezed

# 如果需要 JSON 序列化
flutter pub add json_annotation
flutter pub add --dev json_serializable

引入build_runner后可以通过执行dart run build_runner build --delete-conflicting-outputs自动注解

如果遇到 invalid_annotation_target 警告,可以在 analysis_options.yaml 加:

makefile 复制代码
analyzer:  
errors:  
invalid_annotation_target: ignore

应用场景

  • DTO / Model 写法

    比如用户接口返回:

    json 复制代码
    {
      "id": "u001",
      "nickname": "Tom",
      "avatar_url": "https://xxx.com/a.png",
      "tags": ["vip", "new"]
    }

    推荐这样写:

    dart 复制代码
    import 'package:freezed_annotation/freezed_annotation.dart';
    
    part 'user_dto.freezed.dart';
    part 'user_dto.g.dart';
    
    @freezed
    abstract class UserDto with _$UserDto {
      const factory UserDto({
        required String id,
    
        @Default('') String nickname,
    
        @JsonKey(name: 'avatar_url')
        String? avatarUrl,
    
        @Default(<String>[])
        List<String> tags,
      }) = _UserDto;
    
      factory UserDto.fromJson(Map<String, Object?> json) =>
          _$UserDtoFromJson(json);
    }

    使用:

    ini 复制代码
    final user = UserDto.fromJson(json);
    
    final updated = user.copyWith(
      nickname: 'Jerry',
    );

    Freezed 会自动生成不可变字段、copyWithtoString==hashCode;如果定义了 fromJson,还会配合 json_serializable 生成序列化逻辑。

  • 页面状态初始化写法

  1. 例如类似搜索页这种有个初始页面状态的,可以这样管理

    dart 复制代码
    ///页面状态有这几样的,推荐这样管理
    ///initial:还没开始请求,或者等待用户输入  
    ///loading:正在加载  
    ///success:加载成功,有数据  
    ///failure:加载失败  
    ///empty:加载成功,但无数据
    ///用户详情页  
    ///订单详情页  
    ///房间详情页  
    ///商品详情页  
    ///搜索结果页  
    ///消息列表页  
    ///基金持仓页
    @freezed  
    sealed class UserPageState with _$UserPageState {  
    const factory UserPageState.initial() = UserPageInitial;  
    
    const factory UserPageState.loading() = UserPageLoading;  
    
    const factory UserPageState.empty() = UserPageEmpty;  
    
    const factory UserPageState.success({  
    required List<UserDto> users,  
    @Default(false) bool isRefreshing,  
    @Default(false) bool isLoadingMore,  
    @Default(false) bool hasMore,  
    }) = UserPageSuccess;  
    
    const factory UserPageState.failure({  
    required String message,  
    }) = UserPageFailure;  
    }
  2. 类似用户详情页状态,则直接用AsyncValue表示即可

    scss 复制代码
    /// provider
    final userDetailProvider = FutureProvider.family<UserDto, String>((ref, userId) async {
      final repository = ref.watch(userRepositoryProvider);
      return repository.fetchUserDetail(userId);
    });
    /// 页面
    Widget build(BuildContext context, WidgetRef ref) {  
    final userAsync = ref.watch(userDetailProvider(userId));  
    
    return switch (userAsync) {  
    AsyncLoading() => const Center(  
    child: CircularProgressIndicator(),  
    ),  
    
    AsyncError(:final error) => ErrorView(  
    message: error.toString(),  
    ),  
    
    AsyncData(:final value) => UserDetailView(  
    user: value,  
    ),  
    
    _ => const SizedBox.shrink(),  
    };  
    }
  • 默认值
less 复制代码
///不写nullable,写默认值  
@Default('') String title  
@Default(0) int count  
@Default(false) bool selected  
@Default(<ItemDto>[]) List<ItemDto> items
  • 嵌套json时需要用@JsonSerializable(explicitToJson: true)
scala 复制代码
@freezed
abstract class RoomDto with _$RoomDto {
  @JsonSerializable(explicitToJson: true)
  const factory RoomDto({
    required String id,
    required UserDto owner,
    @Default(<UserDto>[]) List<UserDto> members,
  }) = _RoomDto;

  factory RoomDto.fromJson(Map<String, Object?> json) =>
      _$RoomDtoFromJson(json);
}
相关推荐
恋猫de小郭4 小时前
Amper 正式转正 Kotlin Toolchain ,Gradle 未来何去何从
android·前端·flutter
张风捷特烈4 小时前
Flutter 类库大揭秘#02 | path_provider 各平台实现
前端·flutter
TT_Close1 天前
别劝退了!5秒搞定 Flutter 鸿蒙 FVM 起跑线
flutter·harmonyos·visual studio code
你听得到111 天前
用户说 App 卡,但说不清在哪?我把 Flutter 监控 SDK 升级成了链路观测工作台
前端·flutter·性能优化
stringwu3 天前
Flutter 开发必备:MVI 架构的高效实现指南
前端·flutter
程序员老刘4 天前
Flutter版本选择指南:3.44系列继续观望 | 2026年6月
flutter·ai编程·客户端
37手游移动客户端团队4 天前
招聘-高级安卓开发工程师
android·客户端
逸铭4 天前
Day 4:登录与 Token——桌面端怎么存密钥
前端·客户端
用户965597361905 天前
Provider vs Bloc vs GetX vs Riverpod:Flutter 状态管理方案怎么选?
flutter
恋猫de小郭5 天前
Flutter Patchwork,不用 Fork 改依赖包源码的第三方工具
android·前端·flutter