前言
背景
最近正在学习 flutter,准备手头的公司项目用 flutter 实现。但是碰到一个很现实的问题,就是 dart 的强类型特征。强类型自然有其好处,但是也有其弊端,就是定义实在是太麻烦了,我只写了一个类,因为这个类有 30 多个字段,然后我先写类的成员属性,再写构造函数,再写命名构造函数,就几乎崩溃了。然后发现还有一个要把实例序列化,好保存在 SQLite 里的需求,又多出一个只是转当前成员属性类型的方法,快把我弄崩溃了。
环境
- Dart:2.7.1;
- build_runner:1.8.0;
- json_serializable:3.2.5;
目标
不需要手写序列化和反序列化的方法。
解决方案
后来在 flutter 官网上发现是有这样的解决方案的。就是这个解决方案写的不是很详细,很多操作细节都是分散的,因此在此记录一下。
安装相关依赖
在 pubspec.yaml
文件中加入两个依赖声明。
dev_dependencies:
build_runner: ^1.8.0
json_serializable: ^3.2.5
然后手动安装。友情提示:最好修改成国内源。
$ pub get # dart
$ flutter pub get # flutter
创建要序列化和反序列化的类文件
我们先创建一个 dog.dart
类文件。
import 'package:json_annotation/json_annotation.dart';
// 编辑器可能会提示错误,暂时不用管
part 'dog.g.dart';
@JsonSerializable(nullable: false)
class Dog {
final int id;
final String name;
final int age;
Dog({this.id, this.name, this.age});
}
使用命令行工具生成序列化和反序列化代码
这步一开始是最让我困惑的,不知道例子中的 *.g.dart
文件怎么来的,一开始还以为是手写的。查了一些资料以后才知道是靠命令行工具生成的。
$ pub run build_runner build # dart
$ flutter pub run build_runner build # flutter
运行成功后,就会发现自动生成了一个 dog.g.dart
文件。
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'dog.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
Dog _$DogFromJson(Map<String, dynamic> json) {
return Dog(
id: json['id'] as int,
name: json['name'] as String,
age: json['age'] as int,
);
}
Map<String, dynamic> _$DogToJson(Dog instance) => <String, dynamic>{
'id': instance.id,
'name': instance.name,
'age': instance.age,
};
修改要序列化和反序列化的类文件
import 'package:json_annotation/json_annotation.dart';
part 'dog.g.dart';
@JsonSerializable(nullable: false)
class Dog {
final int id;
final String name;
final int age;
Dog({this.id, this.name, this.age});
// 增加序列化方法
Map<String, dynamic> toMap() => _$DogToJson(this);
// 增加反序列化方法
factory Dog.fromJson(Map<String, dynamic> json) => _$DogFromJson(json);
}
然后就可以正常使用啦!