一行命令将Json文件转成Dart-类

14次阅读

共计 2816 个字符,预计需要花费 8 分钟才能阅读完成。

Flutter 官方提供的 Json 转 Dart 类的方案需要先手动写一个 Dart model 类,然后通过 build_runner 和 json_serializable 包提供的相关命令和标注然后再自动生成 toJson()fromJson方法,这种方案最大问题在于需要开发者手动写一个 Model 类 。在一个项目中,我们需要的 Model 类可能非常多,如果都需要手动反复去做的话会很麻烦、无味。为了解决这个问题,我们做了一个新的开发工具 package Json_model, 使用它,可以只用一行命令,就能将 Json 文件转成 Dart 类,我们再也不用手动去写 Dart 类。

安装

请参考 Github 文档。

使用

  1. 在工程根目录下创建一个名为 “jsons” 的目录;
  2. 创建或拷贝 Json 文件到 ”jsons” 目录中 ;
  3. 运行 pub run json_model (Dart VM 工程)or flutter packages pub run json_model(Flutter 中) 命令生成 Dart model 类,生成的文件默认在 ”lib/models” 目录下

例子

Json 文件: jsons/user.json

{
  "name":"wendux",
  "father":"$user", // 可以通过 "$" 符号引用其它 model 类
  "friends":"$[]user", // 可以通过 "$[]" 来引用数组
  "keywords":"$[]String", // 同上
  "age":20
}

生成的 Dart model 类:

import 'package:json_annotation/json_annotation.dart';
part 'user.g.dart';

@JsonSerializable()
class User {User();
    
    String name;
    User father;
    List<User> friends;
    List<String> keywords;
    num age;
    
    factory User.fromJson(Map<String,dynamic> json) => _$UserFromJson(json);
    Map<String, dynamic> toJson() => _$UserToJson(this);
}

@JsonKey

您也可以使用 json_annotation 包中的“@JsonKey”标注特定的字段。

这个功能在特定场景下非常有用,比如 Json 文件中有一个字段名为 ”+1″,由于在转成 Dart 类后,字段名会被当做变量名,但是在 Dart 中变量名不能包含“+”,我们可以通过“@JsonKey”来映射变量名;

{"@JsonKey(ignore: true) dynamic":"md",
  "@JsonKey(name:'+1') int": "loved", // 将“+1”映射为“loved”"name":"wendux",
  "age":20
}

生成文件如下:

import 'package:json_annotation/json_annotation.dart';
part 'user.g.dart';

@JsonSerializable()
class User {User();
    @JsonKey(name: '+1') int loved;
    String name;
    num age;
    
    factory User.fromJson(Map<String,dynamic> json) => _$UserFromJson(json);
    Map<String, dynamic> toJson() => _$UserToJson(this);
}

测试:

import 'models/index.dart';

void main() {var u = User.fromJson({"name": "Jack", "age": 16, "+1": 20});
  print(u.loved); // 20
}

关于 @JsonKey标注的详细内容请参考 json_annotation 包;

@Import

另外,提供了一个 @Import 指令,该指令可以在生成的 Dart 类中导入指定的文件:

{
  "@import":"test_dir/profile.dart",
  "@JsonKey(ignore: true) Profile":"profile",
  "name":"wendux",
  "age":20
}

生成的 Dart 类:

import 'package:json_annotation/json_annotation.dart';
import 'test_dir/profile.dart';  // 指令生效
part 'user.g.dart';

@JsonSerializable()
class User {User();

    @JsonKey(ignore: true) Profile profile; //file
    String name;
    num age;
    
    factory User.fromJson(Map<String,dynamic> json) => _$UserFromJson(json);
    Map<String, dynamic> toJson() => _$UserToJson(this);
}

更完整的示例请移步这里 .

命令参数

默认的源 json 文件目录为根目录下名为 “json” 的目录;可以通过 src 参数自定义源 json 文件目录,例如:

pub run json_model src=json_files 

默认的生成目录为 ”lib/models”,同样也可以通过dist 参数来自定义输出目录:

pub run json_model src=json_files  dist=data # 输出目录为 lib/data

注意,dist 会默认已 lib 为根目录。

代码调用

如果您正在开发一个工具,想在代码中使用 json_model,此时便不能通过命令行来调用 json_model,这是你可以通过代码调用:

import 'package:json_model/json_model.dart';
void main() {run(['src=jsons']);  //run 方法为 json_model 暴露的方法;}

和可视化生成工具对比

也有一些 IDE 插件提供了 Json 转 Dart 类的功能,它们和 Json_model 相比:

  1. Json_model 需要单独维护一个存放 Json 文件的文件夹,如果有改动,只需修改 Json 文件便可重新生成 Model 类;而 IDE 插件一般需要用户手动将 Json 内容拷贝复制到一个输入框中,这样生成之后 Json 文件没有存档的化,之后要改动就需要手动。
  2. Json_model 可以手动指定某个字段引用的其它 Model 类,可以避免生成重复的类;而 IDE 插件一般会为每一个 Json 文件中所有嵌套对象都单独生成一个 Model 类,即使这些嵌套对象可能在其它 Model 类中已经生成过。
  3. Json_model 提供了命令行转化方式,可以方便集成到 CI 等非 UI 环境的场景。

最后

如果觉得对您有用,欢迎 Star,Github Json_model 项目地址。

正文完
 0