跳到主要内容

build value使用介绍

 实际开发过程中,不可避免的要和服务端进行数据交互。json 是一种可读性强应用广泛的协议。Java 语言中,有 Gson,Jackson,fastjson 这样的序列化包,但 Dart 里没有。这是因为这些包实现序列化依赖反射,而反射与缩小包体积的算法tree shaking相冲突。所以在 Dart 里使用 build_value 这样的工具生成序列化的代码。

1.添加依赖

build_value 是一个三方包,和 Java 里面的 Lombok 有点类似,需要添加以下依赖。

dependencies:
built_collection: ^5.0.0
built_value: ^8.4.0

dev_dependencies:
build_runner: ^1.0.0
built_value_generator: ^8.4.0

2. 配置Vs Code代码模板

build_value 会自动识别需要生成代码的类,这些类的格式固定。在 Vs Code 里可以配置模板:文件→首选项→配置用户代码片段,搜索dart.json,将下面的内容拷贝进去。

{
"Built Value": {
"prefix": "blt",
"body": [
"abstract class ${1} implements Built<${1}, ${1}Builder> {",
"\t${0:// fields go here}",
"",
"\t${1}._();",
"",
"\tfactory ${1}([updates(${1}Builder b)]) = _$${1};",
"}"
],
"description": "Built Value Class"
},
"Built Value Serializable": {
"prefix": "blts",
"body": [
"abstract class ${1} implements Built<${1}, ${1}Builder> {",
"\t${0:// fields go here}",
"",
"\t${1}._();",
"",
"\tfactory ${1}([updates(${1}Builder b)]) = _$${1};",
"",
"\tString toJson() {",
"\t\treturn json.encode(serializers.serializeWith(${1}.serializer, this));",
"\t}",
"",
"\tstatic ${1}? fromJson(String jsonString) {",
"\t\treturn serializers.deserializeWith(${1}.serializer, json.decode(jsonString));",
"\t}",
"",
"\tstatic Serializer<${1}> get serializer => _$${1/(^[A-z]{1})/${1:/downcase}/}Serializer;",
"}"
],
"description": "Serializable Built Value Class"
},
"Built Value Header": {
"prefix": "blth",
"body": [
"library ${1};",
"",
"import 'dart:convert';",
"",
"import 'package:built_collection/built_collection.dart';",
"import 'package:built_value/built_value.dart';",
"import 'package:built_value/serializer.dart';",
"",
"part '${1}.g.dart';",
],
"description": "Built Value Imports and File Header"
},
}

3. 编写代码

 新建一个 person.dart 文件,输入blth,插件自动补充 build_value 的头。

自动填充build value头

 输入blt会补充内容。

自动填充build value代码

 执行命令flutter packages pub run build_runner build即可完成自动生成。此时目录下会多出一个 person.g.dart 文件。


提示

build_value 支持监控文件变化,自动生成代码。使用命令flutter packages pub run build_runner watch即可

4. builder使用

 这里定义了person类,它包含了两个属性:nameaddress

abstract class Person implements Built<Person, PersonBuilder> {
// fields go here
String get name;
String get address;

Person._();

factory Person([updates(PersonBuilder b)]) = _$Person;
}

 使用时,传入一个 builder 到构造函数中。这里..被称为级联操作符

Person p = Person((b) => b
..name = "lily"
..address = "jiangxi");

 如果 builder 没有指定某个属性的值,此时程序会崩溃。需要在可以为空的属性前加上?

abstract class Person implements Built<Person, PersonBuilder> {
// fields go here
String? get name;
String get address;

Person._();

factory Person([updates(PersonBuilder b)]) = _$Person;
}

5. rebuild生成新对象

build_value 没有 setter 方法,如果想修改某些属性,可以使用rebuild方法重新生成一个对象。

Person q = p.rebuild((b) => b..address = "sichuang");

6. build collectoin使用

 当属性值为集合时,可以使用 build_value 里的 build collcetion 。定义属性类型时,需要指定集合,下面例子定义了phones这个 listbags这个 set

abstract class Person implements Built<Person, PersonBuilder> {
// fields go here
String? get name;
String get address;

BuiltList<String> get phones;

BuiltSet<String> get bags;

Person._();

factory Person([updates(PersonBuilder b)]) = _$Person;
}

 使用时,可以向对应的集合添加所需的元素。

Person p = Person((b) => b
..address = "jiangxi"
..name = "lily"
..bags.addAll(['bag1', 'bag2'])
..phones.addAll(['phone1', 'phone2']));

7. serializer使用

 和前面类似,在Vs code 里输入blts,插件就会自动补全代码。输入类名之后记得按下tab,这样serializer才会变成驼峰结构。

自动填充序列化代码

 接下来需要新建serializers.dart,和模型类似,先使用blth声明头信息。然后定义serializer

library serializers;

import 'dart:convert';

import 'package:built_collection/built_collection.dart';
import 'package:built_value/built_value.dart';
import 'package:built_value/serializer.dart';
import 'package:flutter_application_1/model/student.dart';

part 'serializers.g.dart';

@SerializersFor([Student])
final Serializers serializers = _$serializers;

 这时就可以在其他地方使用toJsonfromJson方法了。

void main() {
Student s = Student((b) => b
..name = "lily"
..address = "qinhai");
print(s.toJson());
}

8. 使用标准json序列化

 细心的读者会发现,build_value 序列化方式和标准的序列化方式不一样,可以修改serializer,使用标准的序列化方式。

@SerializersFor([Student])
final Serializers serializers =
(_$serializers.toBuilder()..addPlugin(StandardJsonPlugin())).build();

  1. Built Value Tutorial for Dart & Flutter

  2. Youtube video

  3. JSON and serialization

署名-非商业性使用-禁止演绎 4.0 国际