美文网首页flutter实战技术
flutter json转model框架json_seriali

flutter json转model框架json_seriali

作者: 江水东流 | 来源:发表于2024-01-30 17:49 被阅读0次

    如何在编译器动态生成一些代码,实现一些功能?
    我们用很多flutter插件时候,会动态生成一些文件,它们是如何实现的?

    我自己实现一个简单的json_serializable框架,让你理解flutter中动态生成代码是如何实现的

    1
    pubspec.yaml里面加入
    dev_dependencies
    build_runner: ^2.4.8
    source_gen: ^1.5.0

    2
    生成一个注解类,注解类就是@override这种,
    要有个const构造方法,主要是写在别的方法或者类上面标注下,让编译器识别,可以执行特殊操作

    class JsonAnnotation {
      const JsonAnnotation();
    }
    
    再新建一个文件test_model 写一个model,  model顶部@注解类
    import 'package:my_app/builder/zhujie/json_annotation.dart';
    
    @JsonAnnotation()
    class TestModel {
      String name;
      int age;
      TestModel(this.name, this.age);
    }
    
    

    3
    新建一个json_builder.dart类
    这个类就是生成的代码文件名字,以及生成代码逻辑所在,你可以仿照下面逻辑,实现自己的需求

    <JsonAnnotation> 就是把有上面注解JsonAnnotation的类都执行下下面生成代码的操作,

    import 'package:analyzer/dart/element/element.dart';
    import 'package:build/build.dart';
    import 'package:my_app/builder/zhujie/json_annotation.dart';
    import 'package:source_gen/source_gen.dart';
    
    // LibraryBuilder 生成独立的dart文件
    Builder testJsonBuilder(BuilderOptions options) =>
        LibraryBuilder(JsonBuilder());
    
    class JsonBuilder extends GeneratorForAnnotation<JsonAnnotation> {
      @override
      generateForAnnotatedElement(
          Element element, ConstantReader annotation, BuildStep buildStep) {
        if (element is! ClassElement) {
          throw InvalidGenerationSource('入参必须是个class', element: element);
        }
    
        var className = element.name;
        final buffer = StringBuffer();
        buffer.writeln('import \'${element.librarySource.shortName}\';');
        buffer.writeln('extension ${className}JsonExtension on $className {');
        buffer.writeln('   Map<String, dynamic> toJson() {');
        buffer.writeln('    final Map<String, dynamic> data = {};');
        for (var field in element.fields) {
          buffer.writeln('    data[\'${field.name}\'] = ${field.name};');
        }
        buffer.writeln('    return data;');
    
        buffer.writeln('    }');
    
        buffer.writeln('static fromJson(Map<String, dynamic> json) {');
        buffer.writeln('  return $className(');
        for (var field in element.fields) {
          buffer.writeln('      json[\'${field.name}\'],');
        }
    
        buffer.writeln('    );');
        buffer.writeln('}');
        buffer.writeln('    }');
    
        return buffer.toString();
      }
    
    }
    
    

    4
    pubspec.yaml 同级目录新建一个 build.yaml文件,写入执行上面代码配置
    配置刚才写的代码路径,入口函数名字testJsonBuilder,把.dart文件生成一个.g.dart文件
    这是上面代码执行入口,配置完成后 执行命令就可以运行生成代码逻辑

    builders:
      testJsonBuilder:
        import: "package:my_app/builder/json_builder.dart"
        builder_factories: [ "testJsonBuilder" ]
        build_extensions: { '.dart': [ '.g.dart' ] }
        build_to: source
        auto_apply: root_package
    

    5 cd到项目跟目录,命令行执行命令

    dart run build_runner build
    

    运行结束就生成了一个test_model.g.dart 文件
    里面内容如下,下面内容都是上面第三步写出来的,你可以按照你的需求生产任何代码

    import 'test_model.dart';
    
    extension TestModelJsonExtension on TestModel {
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = {};
        data['name'] = name;
        data['age'] = age;
        return data;
      }
    
      static fromJson(Map<String, dynamic> json) {
        return TestModel(
          json['name'],
          json['age'],
        );
      }
    }
    

    6 测试model转json

      test() {
        TestModel testModel = TestModel('中国', 18);
        Map<String, dynamic> map = testModel.toJson();
        jdLog('map---$map');
        TestModel newModel = TestModelJsonExtension.fromJson(map);
        jdLog('newModel---${newModel.name}  ${newModel.age}');
      }
    
    打印结果如下
    flutter: [home_page.dart line:32] map---{name: 中国, age: 18}
    flutter: [home_page.dart line:34] newModel---中国  18
    

    说明我们实现了一个简单的json转model插件,复杂功能的话,你自己完善逻辑就好了,demo地址 https://gitee.com/kuaipai/my_app.git

    相关文章

      网友评论

        本文标题:flutter json转model框架json_seriali

        本文链接:https://www.haomeiwen.com/subject/fgfoodtx.html