MXFlutter:基於JS的Flutter框架,用JS也能寫出Flutter應用

Gitee發表於2020-07-03

MXFlutter:基於JS的Flutter框架,用JS也能寫出Flutter應用

專案名稱:MXFlutter

專案作者:MXFlutter Team

開源許可協議:MIT

專案地址:https://gitee.com/huoxd/MXFlutter

專案簡介

MXFlutter 是一套基於 JavaScript 的 Flutter 框架,可以用極其類似 Dart 的開發方式,通過編寫 JavaScript 程式碼,來開發 Flutter 應用,或者使用 mxjsbuilder 編譯器,把現有Flutter 工程編譯為JS,執行在 mxflutter 之上。

專案特性

  • 支援Dart Flutter語法
  • 支援定義Flutter中同名Widget類
  • 支援定義相同的Build方式,SetState重新整理及事件響應方法
  • 支援js模組化開發
  • 支援模擬器頁面熱更新

核心思想

把 Flutter 的渲染邏輯中的三棵樹(即:WidgetTree、Element、RenderObject )中的第一棵(即:WidgetTree),放到 JavaScript 中生成。用 JavaScript 完整實現了 Flutter 控制元件層封裝,可以使用 JavaScript,用極其類似 Dart 的開發方式,開發Flutter應用,利用JavaScript版的輕量級Flutter Runtime,生成UI描述,傳遞給Dart層的UI引擎,UI引擎把UI描述生產真正的 Flutter 控制元件。所以,它在iOS上是完全動態化的。

專案結構

MXFlutter,就是用JavaScript,以Flutter的寫法開發Flutter。具體的專案結構分為三層,請看下圖:

MXFlutter:基於JS的Flutter框架,用JS也能寫出Flutter應用

1.VM層:

  • MXFlutter Runtime
  • 定義和Flutter Widget同名映象類
  • 響應式UI框架

2.Flutter層:

  • Script指令碼管理模組
  • DSL2Widget UIEngine,事件支援
  • Dart業務API支援
  • 記憶體管理,物件生命週期管理

3.Native層:

  • VM虛擬機器
  • 執行緒管理
  • Native業務API支援

專案效果 UI 展示

單頁面演示

MXFlutter:基於JS的Flutter框架,用JS也能寫出Flutter應用

下面是UI截圖對應的JS程式碼,沒錯,你沒有眼花,這個是真的 JavaScript 程式碼,可以在 MXFlutter 的執行時庫上渲染出 Flutter 的UI,(是不是很像Flutter裡面的元件程式碼)!

class JSPestoPage extends MXJSWidget {
  constructor() {
    super("JSPestoPage");
    this.recipes = recipeList;


  }


  build(context) {
    let statusBarHeight = 24;
    let mq = MediaQuery.of(context);
    if (mq) {
      statusBarHeight = mq.padding.top
    }


    let w = new Scaffold({
      appBar: new AppBar({
        title: new Text("Pesto Demo")
      }),
      floatingActionButton: new FloatingActionButton({
        child: new Icon(new IconData(0xe3c9)),
        onPressed: function () {


        },
      }),
      body: new CustomScrollView({
        semanticChildCount: this.recipes.length,
        slivers: [
          //this.buildAppBar(context, statusBarHeight),
          this.buildBody(context, statusBarHeight),
        ],
      }),
      //body:this.buildItems()[0]
    });


    return w;
  }


  buildAppBar(context, statusBarHeight) {
    return SliverAppBar({
      pinned: true,
      expandedHeight: _kAppBarHeight,
      actions: [
        IconButton({
          icon: new Icon(new IconData(1)),
          tooltip: 'Search',
          onPressed: function () {


          },
        }),
      ],
      flexibleSpace: LayoutBuilder({
        builder: function (context, constraints) {
          size = constraints.biggest;
          appBarHeight = size.height - statusBarHeight;
          t = (appBarHeight - kToolbarHeight) / (_kAppBarHeight - kToolbarHeight);
          extraPadding = new Tween({ begin: 10.0, end: 24.0 }).transform(t);
          logoHeight = appBarHeight - 1.5 * extraPadding;
          return Padding({
            padding: EdgeInsets.only({
              top: statusBarHeight + 0.5 * extraPadding,
              bottom: extraPadding,
            }),
            child: Center({
              child: new Icon(new IconData(1))
            }),
          });
        },
      }),
    });
  }


  buildBody(context, statusBarHeight) {


    let mediaPadding = EdgeInsets.all(0);
    let mq = MediaQuery.of(context);
    if (mq) {
      mediaPadding = MediaQuery.of(context).padding;
    }
    let padding = EdgeInsets.only({
      top: 8.0,
      left: 8.0 + mediaPadding.left,
      right: 8.0 + mediaPadding.right,
      bottom: 8.0
    });


    return new SliverPadding({
      padding: padding,
      sliver: new SliverGrid({
        gridDelegate: new SliverGridDelegateWithMaxCrossAxisExtent({
          maxCrossAxisExtent: _kRecipePageMaxWidth,
          crossAxisSpacing: 8.0,
          mainAxisSpacing: 8.0,
        }),
        delegate: new SliverChildBuilderDelegate(
          function (context, index) {
            let recipe = this.recipes[index];
            let w = new RecipeCard({
              recipe: recipe,
              onTap: function () { showRecipePage(context, recipe); },
            });


            return w;
          },
          {
            childCount: this.recipes.length,
          }),
      }),
 複製程式碼


如果你想要了解它更詳細的使用和接入方法,那麼就點選後面的連結前往專案主頁看看吧:gitee.com/huoxd/MXFlu…


相關文章