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);
}
相关推荐
阿里云云原生12 小时前
还原一次用户等待:深度解析 Flutter RUM SDK 如何打通 Dart 到 Native 的观测链路
flutter
_阿南_14 小时前
flutter 展示的字体突然奔放了
android·flutter·ios
GitLqr17 小时前
玩转 Dart typedef:不仅是函数别名那么简单
flutter·面试·dart
FungLeo19 小时前
Flutter 两个反直觉布局坑:ListTile 水波纹 / VerticalDivider 踩坑实录
android·flutter
年小个大1 天前
受 go-zero 启发,我给 Flutter 写了一套 CLI 脚手架
android·flutter·架构
FungLeo2 天前
Flutter 骨架屏 Shimmer 实现:不用 transform 的扫光法实战
前端·javascript·flutter
GitLqr2 天前
Flutter 居然能直接跑在 Apple Watch 上了?玩转 flutter-watchos
flutter·全栈·apple watch
你听得到112 天前
排查 App 问题:别只盯着报错,把前后发生的事情串起来
android·前端·flutter
CappuccinoRose2 天前
前端存储体系学习总结文档
前端·客户端·cookie·ssr·服务端·localstorage·sessionstorage
天空之城--2 天前
近一周Android Flutter行业动态与实用参考
android·flutter