Flutter JSON转Model插件json_to_model的使用

Flutter JSON转Model插件json_to_model的使用

json_to_model 是一个命令行工具,用于从 JSON 文件生成 Dart 模型。

特性

功能 状态
零安全
toJson/fromJson
不可变类
copyWith生成
克隆和深克隆
嵌套JSON类
枚举支持

安装

pubspec.yaml 文件中添加依赖:

dev_dependencies:
  json_to_model: ^3.0.1
  quiver: ^3.0.1+1

安装依赖:

# 使用命令行安装
pub get

# 或者使用 Dart 的 IDE(如 VSCode 或 Android Studio)中的安装选项。

这个库的功能是什么?

json_to_model 是一个命令行工具,用于将 .json 文件转换为不可变的 .dart 模型。

开始使用

该命令会遍历你的 JSON 文件,并找到可能的类型、变量名、导入 URI、装饰器和类名,然后将其写入模板。

  1. 在项目的根目录下创建/复制 .json 文件到 ./jsons/ 目录(默认)。
  2. 运行 flutter pub run json_to_model

示例

输入

考虑以下名为 product.jsonemployee.json 的文件。

product.json:

{
  "id": "123",
  "caseId?": "123",
  "startDate?": "2020-08-08",
  "endDate?": "2020-10-10",
  "placementDescription?": "Description string"
}

employee.json:

{
  "id": "123",
  "displayName?": "Jan Jansen",
  "@ignore products?": "$[]product"
}

输出

这将生成 product.dartemployee.dart

product.dart:

import 'package:flutter/foundation.dart';

[@immutable](/user/immutable)
class Product {

  const Product({
    required this.id,
    this.caseId,
    this.startDate,
    this.endDate,
    this.placementDescription,
  });

  final String id;
  final String? caseId;
  final String? startDate;
  final String? endDate;
  final String? placementDescription;

  factory Product.fromJson(Map<String,dynamic> json) => Product(
    id: json['id'] as String,
    caseId: json['caseId'] != null ? json['caseId'] as String : null,
    startDate: json['startDate'] != null ? json['startDate'] as String : null,
    endDate: json['endDate'] != null ? json['endDate'] as String : null,
    placementDescription: json['placementDescription'] != null ? json['placementDescription'] as String : null
  );

  Map<String, dynamic> toJson() => {
    'id': id,
    'caseId': caseId,
    'startDate': startDate,
    'endDate': endDate,
    'placementDescription': placementDescription
  };

  Product clone() => Product(
    id: id,
    caseId: caseId,
    startDate: startDate,
    endDate: endDate,
    placementDescription: placementDescription
  );

  Product copyWith({
    String? id,
    String? caseId,
    String? startDate,
    String? endDate,
    String? placementDescription
  }) => Product(
    id: id ?? this.id,
    caseId: caseId ?? this.caseId,
    startDate: startDate ?? this.startDate,
    endDate: endDate ?? this.endDate,
    placementDescription: placementDescription ?? this.placementDescription,
  );

  [@override](/user/override)
  bool operator ==(Object other) => identical(this, other)
    || other is Product && id == other.id && caseId == other.caseId && startDate == other.startDate && endDate == other.endDate && placementDescription == other.placementDescription;

  [@override](/user/override)
  int get hashCode => id.hashCode ^ caseId.hashCode ^ startDate.hashCode ^ endDate.hashCode ^ placementDescription.hashCode;
}

employee.dart:

import 'package:flutter/foundation.dart';
import 'product.dart';

[@immutable](/user/immutable)
class Employee {

  const Employee({
    required this.id,
    this.displayName,
    this.products,
  });

  final String id;
  final String? displayName;
  final List<Product>? products;

  factory Employee.fromJson(Map<String,dynamic> json) => Employee(
    id: json['id'] as String,
    displayName: json['displayName'] != null ? json['displayName'] as String : null
  );

  Map<String, dynamic> toJson() => {
    'id': id,
    'displayName': displayName
  };

  Employee clone() => Employee(
    id: id,
    displayName: displayName,
    products: products?.map((e) => e.clone()).toList()
  );

  Employee copyWith({
    String? id,
    String? displayName,
    List<Product>? products
  }) => Employee(
    id: id ?? this.id,
    displayName: displayName ?? this.displayName,
    products: products ?? this.products,
  );

  [@override](/user/override)
  bool operator ==(Object other) => identical(this, other)
    || other is Employee && id == other.id
    && displayName == other.displayName
    && products == other.products;

  [@override](/user/override)
  int get hashCode => id.hashCode ^
    displayName.hashCode ^
    products.hashCode;
}

输入

考虑以下名为 location.json 的文件:

{
    "locationId?": 93,
    "locationTypeId?": "1234",
    "updatedAt": "@datetime",
    "name?": "Lunet 10a, Veenendaal",
    "confidential?": false,
    "locationType?": "@enum:INSIDE,OUTSIDE,CLIENT,HOME,ROOM,UNKNOWN",
    "point?": {
        "longitude": 58.1234,
        "latitude": 12.123
    }
}

输出

这将生成 location.dart

import 'package:flutter/foundation.dart';

[@immutable](/user/immutable)
class Location {

  const Location({
    this.locationId,
    this.locationTypeId,
    required this.updatedAt,
    this.name,
    this.confidential,
    this.locationType,
    this.point,
  });

  final int? locationId;
  final String? locationTypeId;
  final DateTime updatedAt;
  final String? name;
  final bool? confidential;
  LocationLocationTypeEnum
    get locationLocationTypeEnum => _locationLocationTypeEnumValues.map[locationType]!;
  final String? locationType;
  final Point? point;

  factory Location.fromJson(Map<String,dynamic> json) => Location(
    locationId: json['locationId'] != null ? json['locationId'] as int : null,
    locationTypeId: json['locationTypeId'] != null ? json['locationTypeId'] as String : null,
    updatedAt: DateTime.parse(json['updatedAt'] as String),
    name: json['name'] != null ? json['name'] as String : null,
    confidential: json['confidential'] != null ? json['confidential'] as bool : null,
    locationType: json['locationType'] != null ? json['locationType'] as String : null,
    point: json['point'] != null ? Point.fromJson(json['point'] as Map<String, dynamic>) : null
  );

  Map<String, dynamic> toJson() => {
    'locationId': locationId,
    'locationTypeId': locationTypeId,
    'updatedAt': updatedAt.toIso8601String(),
    'name': name,
    'confidential': confidential,
    'locationType': _locationLocationTypeEnumValues.reverse[locationType],
    'point': point?.toJson()
  };

  Location clone() => Location(
    locationId: locationId,
    locationTypeId: locationTypeId,
    updatedAt: updatedAt,
    name: name,
    confidential: confidential,
    locationType: locationType,
    point: point?.clone()
  );

  Location copyWith({
    int? locationId,
    String? locationTypeId,
    DateTime? updatedAt,
    String? name,
    bool? confidential,
    String? locationType,
    Point? point
  }) => Location(
    locationId: locationId ?? this.locationId,
    locationTypeId: locationTypeId ?? this.locationTypeId,
    updatedAt: updatedAt ?? this.updatedAt,
    name: name ?? this.name,
    confidential: confidential ?? this.confidential,
    locationType: locationType ?? this.locationType,
    point: point ?? this.point,
  );

  [@override](/user/override)
  bool operator ==(Object other) => identical(this, other)
    || other is Location && locationId == other.locationId && locationTypeId == other.locationTypeId && updatedAt == other.updatedAt && name == other.name && confidential == other.confidential && locationType == other.locationType && point == other.point;

  [@override](/user/override)
  int get hashCode => locationId.hashCode ^ locationTypeId.hashCode ^ updatedAt.hashCode ^ name.hashCode ^ confidential.hashCode ^ locationType.hashCode ^ point.hashCode;
}

enum LocationLocationTypeEnum { INSIDE, OUTSIDE, CLIENT, HOME, ROOM, UNKNOWN }

extension LocationLocationTypeEnumEx on LocationLocationTypeEnum{
  String? get value => _locationLocationTypeEnumValues.reverse[this];
}

final _locationLocationTypeEnumValues = _LocationLocationTypeEnumConverter({
  'INSIDE': LocationLocationTypeEnum.INSIDE,
  'OUTSIDE': LocationLocationTypeEnum.OUTSIDE,
  'CLIENT': LocationLocationTypeEnum.CLIENT,
  'HOME': LocationLocationTypeEnum.HOME,
  'ROOM': LocationLocationTypeEnum.ROOM,
  'UNKNOWN': LocationLocationTypeEnum.UNKNOWN,
});

class _LocationLocationTypeEnumConverter<String, O> {
  final Map<String, O> map;
  Map<O, String>? reverseMap;

  _LocationLocationTypeEnumConverter(this.map);

  Map<O, String> get reverse => reverseMap ??= map.map((k, v) => MapEntry(v, k));
}

[@immutable](/user/immutable)
class Point {

  const Point({
    required this.longitude,
    required this.latitude,
  });

  final double longitude;
  final double latitude;

  factory Point.fromJson(Map<String,dynamic> json) => Point(
    longitude: json['longitude'] as double,
    latitude: json['latitude'] as double
  );

  Map<String, dynamic> toJson() => {
    'longitude': longitude,
    'latitude': latitude
  };

  Point clone() => Point(
    longitude: longitude,
    latitude: latitude
  );

  Point copyWith({
    double? longitude,
    double? latitude
  }) => Point(
    longitude: longitude ?? this.longitude,
    latitude: latitude ?? this.latitude,
  );

  [@override](/user/override)
  bool operator ==(Object other) => identical(this, other)
    || other is Point && longitude == other.longitude && latitude == other.latitude;

  [@override](/user/override)
  int get hashCode => longitude.hashCode ^ latitude.hashCode;
}

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

1 回复

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


在Flutter开发中,将JSON数据转换为模型类(Model)是一个常见的需求。为了简化这个过程,可以使用一些工具或插件来自动生成模型类。json_to_model 是一个常用的插件,它可以帮助开发者根据JSON数据自动生成Dart模型类。

安装 json_to_model 插件

首先,你需要在你的Flutter项目中安装 json_to_model 插件。你可以通过以下命令来安装:

flutter pub add json_to_model

或者,你可以在 pubspec.yaml 文件中手动添加依赖:

dependencies:
  json_to_model: ^1.0.0

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

使用 json_to_model 生成模型类

安装完插件后,你可以通过命令行工具来生成模型类。假设你有一个JSON文件 example.json,你可以使用以下命令来生成模型类:

flutter pub run json_to_model:generate -i example.json -o lib/models
  • -i 参数指定输入的JSON文件路径。
  • -o 参数指定输出的Dart文件路径。

示例

假设你有一个 example.json 文件,内容如下:

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

运行以下命令:

flutter pub run json_to_model:generate -i example.json -o lib/models

这将在 lib/models 目录下生成一个 example_model.dart 文件,内容类似于:

import 'dart:convert';

class ExampleModel {
  String name;
  int age;
  String email;
  bool isActive;

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

  factory ExampleModel.fromJson(Map<String, dynamic> json) {
    return ExampleModel(
      name: json['name'],
      age: json['age'],
      email: json['email'],
      isActive: json['isActive'],
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'name': name,
      'age': age,
      'email': email,
      'isActive': isActive,
    };
  }
}

使用生成的模型类

在Flutter应用中使用生成的模型类非常简单。例如,你可以从API获取JSON数据并将其转换为模型对象:

import 'dart:convert';
import 'package:flutter/material.dart';
import 'models/example_model.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('JSON to Model Example'),
        ),
        body: Center(
          child: FutureBuilder<String>(
            future: fetchData(),
            builder: (context, snapshot) {
              if (snapshot.connectionState == ConnectionState.waiting) {
                return CircularProgressIndicator();
              } else if (snapshot.hasError) {
                return Text('Error: ${snapshot.error}');
              } else {
                ExampleModel model = ExampleModel.fromJson(jsonDecode(snapshot.data!));
                return Text('Name: ${model.name}, Age: ${model.age}');
              }
            },
          ),
        ),
      ),
    );
  }

  Future<String> fetchData() async {
    // 模拟从API获取数据
    await Future.delayed(Duration(seconds: 2));
    return '{"name": "John Doe", "age": 30, "email": "john.doe@example.com", "isActive": true}';
  }
}
回到顶部