Flutter JSON数据转换插件json_transform_model的使用

Flutter JSON数据转换插件json_transform_model的使用

json_transform_model 0.0.9

json 转model

只用一行命令,直接将JSON文件转为Dart model类。

flutter packages pub run json_transform_model

安装

pubspec.yaml文件中添加以下依赖:

dependencies:
  flutter:
    sdk: flutter
  ...其他依赖...

dev_dependencies: 
  json_transform_model: # 最新版本
  build_runner: ^2.0.4
  json_serializable: ^4.1.3

使用

  1. 在工程根目录下创建一个名为 jsons 的目录;
  2. 创建或拷贝JSON文件到 jsons 目录中;
  3. 运行以下命令生成Dart model类:
    • 在Dart VM项目中运行:pub run json_model
    • 在Flutter项目中运行:flutter packages pub run json_model 默认生成的文件位于 lib/models 目录下。

将所有JSON文件映射到一个文件 JsonConvert

借鉴 json_model 生成类文件的功能,在这个基础上把所有的JSON文件映射到一个文件 JsonConvert 中,对外提供以下API:

// 根据T和给定的字典数据生成对应的模型
static fromJson<T>(Map<String, dynamic> json) {}

// 根据T和给定的模型生成对应的字典
static Map<String, dynamic> toJson<T>() {}

// 根据对应的list(JSON)批量生成对应的模型数据
static M fromJsonAsT<M>(json) {}

主要用于在网络请求解析数据时提供一个基于泛型的方法,在底层就解析好数据抛给上层来处理。

提供一个 JsonConvert 文件的模板

json_model 的基础上,提供一个 JsonConvert 文件的模板,该模板是动态生成的,无需手动修改。

// 模板内容
import '../models/index.dart';

// 动态生成的文件,不要手动去修改
Type typeOf<T>() => T;

class JsonConvert {
  static fromJson<T>(Map<String, dynamic> json) {
    return _getFromJson<T>(typeOf<T>(), T, json);
  }

  static Map<String, dynamic> toJson<T>() {
    return _getToJson<T>(typeOf<T>(), T);
  }

  static _getFromJson<T>(Type type, data, json) {
    switch (type) {
      $getFromJson
    }
    return data as T;
  }

  static _getToJson<T>(Type type, data) {
    switch (type) {
      $modelToJson
    }
    return data as T;
  }

  static _fromJsonSingle(String type, json) {
    switch (type) {
      $singleJsonToModel
    }
    return null;
  }

  static _getListFromType(String type) {
    switch (type) {
      $listModel
    }
    return null;
  }

  static M fromJsonAsT<M>(json) {
    String type = M.toString();
    if (json is List && type.contains("List<")) {
      String itemType = type.substring(5, type.length - 1);
      List tempList = _getListFromType(itemType);
      json.forEach((itemJson) {
        tempList.add(_fromJsonSingle(
            type.substring(5, type.length - 1), itemJson));
      });
      return tempList as M;
    } else {
      return _fromJsonSingle(M.toString(), json) as M;
    }
  }
}

示例

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(this.name, this.father, this.friends, this.keywords, this.age);

  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:

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

生成的Dart类:

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

@JsonSerializable()
class User {
  User(this.loved, this.name, this.age);

  @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类中导入指定的文件。

示例JSON:

{
  "@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(this.profile, this.name, this.age);

  @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);
}

更完整的示例请移步 GitHub 示例

命令参数

默认的源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
1 回复

更多关于Flutter JSON数据转换插件json_transform_model的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


json_transform_model 是一个用于在 Flutter 中简化 JSON 数据转换的插件。它可以帮助开发者将 JSON 数据快速转换为 Dart 模型类,并支持反向转换。以下是使用 json_transform_model 的基本步骤:

1. 安装插件

首先,你需要在 pubspec.yaml 文件中添加 json_transform_model 依赖:

dependencies:
  flutter:
    sdk: flutter
  json_transform_model: ^1.0.0  # 请使用最新版本

然后运行 flutter pub get 来安装依赖。

2. 创建模型类

假设你有一个如下的 JSON 数据:

{
  "name": "John Doe",
  "age": 30,
  "email": "john.doe@example.com"
}

你可以创建一个 Dart 模型类来表示这个 JSON 数据:

import 'package:json_transform_model/json_transform_model.dart';

@JsonTransformModel()
class User {
  String name;
  int age;
  String email;

  User({required this.name, required this.age, required this.email});

  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
  Map<String, dynamic> toJson() => _$UserToJson(this);
}

3. 生成转换代码

json_transform_model 插件会自动生成 _$UserFromJson_$UserToJson 方法。你需要运行以下命令来生成这些代码:

flutter pub run build_runner build

这将在你的项目目录中生成一个 .g.dart 文件,例如 user.g.dart,其中包含了 _$UserFromJson_$UserToJson 的实现。

4. 使用模型类

现在你可以使用生成的 User 类来转换 JSON 数据:

void main() {
  String jsonString = '''
  {
    "name": "John Doe",
    "age": 30,
    "email": "john.doe@example.com"
  }
  ''';

  Map<String, dynamic> jsonMap = jsonDecode(jsonString);
  User user = User.fromJson(jsonMap);

  print(user.name);  // 输出: John Doe
  print(user.age);   // 输出: 30
  print(user.email); // 输出: john.doe@example.com

  // 将模型转换回 JSON
  Map<String, dynamic> userJson = user.toJson();
  print(userJson);  // 输出: {name: John Doe, age: 30, email: john.doe@example.com}
}

5. 处理复杂 JSON

如果你的 JSON 数据包含嵌套结构或数组,json_transform_model 也可以处理。例如:

{
  "name": "John Doe",
  "age": 30,
  "email": "john.doe@example.com",
  "address": {
    "street": "123 Main St",
    "city": "Anytown",
    "state": "CA"
  },
  "phoneNumbers": [
    {"type": "home", "number": "555-1234"},
    {"type": "work", "number": "555-5678"}
  ]
}

你可以创建嵌套的模型类:

@JsonTransformModel()
class Address {
  String street;
  String city;
  String state;

  Address({required this.street, required this.city, required this.state});

  factory Address.fromJson(Map<String, dynamic> json) => _$AddressFromJson(json);
  Map<String, dynamic> toJson() => _$AddressToJson(this);
}

@JsonTransformModel()
class PhoneNumber {
  String type;
  String number;

  PhoneNumber({required this.type, required this.number});

  factory PhoneNumber.fromJson(Map<String, dynamic> json) => _$PhoneNumberFromJson(json);
  Map<String, dynamic> toJson() => _$PhoneNumberToJson(this);
}

@JsonTransformModel()
class User {
  String name;
  int age;
  String email;
  Address address;
  List<PhoneNumber> phoneNumbers;

  User({
    required this.name,
    required this.age,
    required this.email,
    required this.address,
    required this.phoneNumbers,
  });

  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
  Map<String, dynamic> toJson() => _$UserToJson(this);
}

6. 重新生成代码

每当你的模型类发生变化时,你都需要重新运行以下命令来生成新的代码:

flutter pub run build_runner build
回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!