如果您由其他语言接触到以Dart语法表达的Flutter,您可能会注意到Dart语法 需要为简单的类编写许多样板代码
有时,您需要一个在构造函数中接受分配值的类,来提供有用的toString()覆盖,实现值相等性以及copyWith方法,因此对象可以保持不可变等诸如此类的功能
class MyClass {
const MyClass({
required int id,
required bool isImportant,
});
final int id;
final bool isImportant;
@override
String toString() => 'MyClass(id: $id, isImportant: $isImportant)';
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
other.runtimeType == runtimeType &&
other is MyClass &&
identical(other.id, id) || other.id == id &&
identical(other.isImportant, isImportant) || other.isImportant == isImportant;
}
MyClass copyWith({int? id, bool? isImportant}) =>
MyClass(
id: id ?? this.id,
bool: isImportant ?? this.isImportant,
);
}
但骤然间,类涵盖了这些基本功能就不再简单了。好在有像Freezed这样的代码生成包,让您无须编写数百行容易出错的样板代码
要使用Freezed,请将其作为dev_dependency添加到pubspec.yaml文件中,并新增普通依赖项freezed_annotation
dependencies:
freezed_annotation: any
dev_dependencies:
build_runner: any,
freezed: any
json_serializable: any
如果想用toJson()和fromJson()方法,还需要build_runner来作为dev_dependency和json_serializable,这样便一起就绪了
先用@Freezed()注释来装饰一个类,然后,指定将其纳入的超类
若Linter检查机制无法判读也无妨,Freezed随即就会生成相应代码
接下来从构造函数开始,使用const factory构造函数并将其指向同名并带有下划线前缀的类
同样,这个类还未生成,所以不用太在意Linter的检查结果
接着在此构造函数中指定数据类所需字段,
⚠️请注意,此处不使用正常的this.field name语法,因为这部分将交给Freezed生成
使用@Default装饰器来分配默认值
一旦所有字段都定义过了,加个FromJson构造函数,指示Freezed所需toJson和fromJson方法
这同样指向一个尚未生成的类
返回文件顶部加上这两个part的声明,方便Dart将此三个文件视为一个大文件
part 'my_class.freezed.dart';
part 'my_class.g.dart';
@Freezed()
class MyClass with _$MyClass{
const factory MyClass({
required int id,
@Default(true) bool isImportant,
}) = _MyClass;
factory MyClass.fromJson(Map<String, dynamic> json) => _$MyClassFromJson(json);
}
最后来运行神奇的build_runner命令,以实际生成所缺的部分,大功告成
$ flutter pub run build_runner build --delete-conflicting-outputs
Freezed替您自动生成了单调的样板代码所含的一堆变数,让您能够做应用程序里您感兴趣的部分,
如果将来您需要添加更多的字段,可以把它们作为第一个构造函数的参数,重新运行build命令方才能做您感兴趣的事情
const factory MyClass({
required int id,
@Default(true) bool isImportant,
int age
});
您可以用Freezed做很多事情, 所以一定要考虑它如何使您的代码更容易维护
如果想了解有关freezed 的内容,或者关于Flutter的其他功能,请访问flutter.dev
原文翻译自视频:视频地址