依存関係の追加
pubspec.yamlファイルに必要なパッケージを追加。
dependencies:
flutter:
sdk: flutter
freezed_annotation: ^2.4.1
json_annotation: ^4.8.1
dev_dependencies:
flutter_test:
sdk: flutter
build_runner: ^2.4.6
freezed: ^2.4.5
json_serializable: ^6.7.1
モデルクラスの作成
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:json_annotation/json_annotation.dart';
part 'user.freezed.dart';
part 'user.g.dart';
@freezed
class User with _$User {
const factory User({
required String id,
required String name,
@Default('') String email,
int? age,
}) = _User;
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
}
コード生成の実行
コード作成後に自動生成のコマンドを実行
flutter pub run build_runner build
変更を監視して自動生成したい場合
flutter pub run build_runner watch
生成されたコードの確認
user.freezed.dart
とuser.g.dart
の2つのファイルが自動生成
モデルの使用例
// インスタンスの作成
final user = User(id: '1', name: 'John Doe', email: '[email protected]', age: 30);
// copyWithを使用した不変の更新
final updatedUser = user.copyWith(name: 'Jane Doe', age: 25);
// JSONへの変換
final json = user.toJson();
// JSONからの変換
final userFromJson = User.fromJson(json);
// パターンマッチング
void checkUser(User user) {
user.when(
(id, name, email, age) {
print('User $name with ID $id, email $email and age $age');
},
);
}
freezedの便利な機能
イミュータブルなオブジェクト
-
copyWith()
を使用して新しいインスタンスを作成
等価性の比較
-
==
演算子とhashCode
が自動生成される
パターンマッチング
-
when()
,maybeWhen()
,map()
,maybeMap()
メソッド
ユニオン型(シールドクラス
@freezed
class Result<T> with _$Result<T> {
const factory Result.success(T value) = Success<T>;
const factory Result.error(String message) = Error<T>;
}
トラブルシューティング
flutter pub run build_runner build --delete-conflicting-outputs
VSCodeでのカスタムスニペットの作成
Preferences: Configure User Snippetsでdart.jsonに下記を追加
"Freezed Model": {
"prefix": "fzmodel",
"body": [
"import 'package:freezed_annotation/freezed_annotation.dart';",
"import 'package:json_annotation/json_annotation.dart';",
"",
"part '$TM_FILENAME_BASE.freezed.dart';",
"part '$TM_FILENAME_BASE.g.dart';",
"",
"@freezed",
"class ${1:${TM_FILENAME_BASE/(.*)/${1:/pascalcase}/}} with _$${1:${TM_FILENAME_BASE/(.*)/${1:/pascalcase}/}} {",
" const factory ${1:${TM_FILENAME_BASE/(.*)/${1:/pascalcase}/}}({",
" required ${2:String} ${3:id},",
" $0",
" }) = _${1:${TM_FILENAME_BASE/(.*)/${1:/pascalcase}/}};",
"",
" factory ${1:${TM_FILENAME_BASE/(.*)/${1:/pascalcase}/}}.fromJson(Map<String, dynamic> json) =>",
" _$${1:${TM_FILENAME_BASE/(.*)/${1:/pascalcase}/}}FromJson(json);",
"}"
],
"description": "Create a new Freezed model class"
}
これを設定したら、新しいDartファイルで fzmodel
と入力してTabキーを押すと、テンプレートが挿入されます。
コマンドラインから生成する場合
# 単一のファイルを生成
flutter pub run build_runner build --build-filter="lib/models/user.dart"
# 変更を監視して自動生成
flutter pub run build_runner watch
VSCode固有のショートカット
-
Ctrl+Shift+B
(Windows/Linux) またはCmd+Shift+B
(Mac): タスクを実行(build_runnerコマンドをタスクとして設定可能) -
F5
: デバッグ実行