Flutter Web 与 JS 或 React 通信交互

Flutter Web 的资料真的是太少了啊,可以说是几乎没有。

Flutter Web 很多库基本都用不了。比如 WebView 的库,与JS交互,使用原生的方法根本走不通。


浏览器的项目还是要用前端JS的方式解决。经过了一通折腾,皇天不负苦心人,终于是把路走通了。

目录
1. 与原生JS交互
    1.1 Flutter 调用 Js;
    1.2 Js 调用 Flutter;
2. 与React交互
    2.1 Flutter 调用 React 的 Js 方法;
    2.2 React 调用 Flutter 的方法。

先引入 Flutter 的 JS 库:https://pub.dev/packages/js

dependencies:
  js: ^0.6.7

一、与原生JS交互

1. Flutter 调用 Js

1.1 先在 HTML 提供一个 JS 方法:

js 的代码可以写在 index.html 的代码里:

方法如下:

function getPersonInfo() {
    const Person = {
        name: 'John',
        sex: 'women',
        age: 36,
    }
    const jsonString = JSON.stringify(Person)
    return jsonString;
}

1.2 在 Flutter 调用刚才的 JS 方法:

import 'dart:convert';
import 'package:flutter/material.dart';
import 'dart:js' as js;

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: ElevatedButton(
        child: const Text("调用js代码"),
        onPressed: () {
          // Flutter Web 调用 Js
          var personInfo = js.context.callMethod('getPersonInfo');
          print("personInfo is $personInfo");
        },
      )
    );
  }
}

至此,把 Flutter Web 项目运行一下,就可以在控制台看到运行结果。
非常简单。

2. Js 调用 Flutter 方法

先通过 Flutter 在 js 的 window 中注入一个方法,然后在 js 中调用这个方法。

2.1 先在 Flutter 提供一个方法(详见注释):

import 'dart:convert';
import 'package:flutter/material.dart';
import 'dart:js' as js;

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  // Toast 显示提示信息 - 提供给 JS 的方法
  void toastMsg(String msg) {
    print("address: $msg");
    MyUtils.showToast(msg);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: ElevatedButton(
        child: const Text("调用js代码"),
        onPressed: () {
          // 给 JS 提供一个方法。 js 通过 window 调用
          js.context["toastMsg"] = toastMsg;

          // Flutter Web 调用 Js
          js.context.callMethod('showVersion');
        },
      )
    );
  }
}

2.2 Js端的代码:

function showVersion() {
    // 调用 Flutter 提供的方法
    window.toastMsg("当前版本号为:1.0.0");
}

至此,就实现了 Flutter 与 原生JS 的彼此交互。


原生JS基本只能实现最基础的逻辑,只掌握到这一步几乎毫无意义。目前绝大多数的项目都是 React 或 Vue 框架写的,React 的方法与原生JS还是有一些区别。接下来看一下与 React 的方法交互。

二、Flutter 与 React 交互

学习了上面的方法之后,应该已经明白了其中的原理。 真正做的时候,就会发现有一个难点:React框架打包之后,会对之前的JS方法名进行压缩处理,之前的方法名就变了,会 not found。所以,这里主要处理的就是 React 打包之后如何调用原始的方法。

上面已经知道如何互相交互了,这里就简单点,只列出关键点。

1. 在 React 中编写方法供 Flutter调用

React 可以做一些自己业务,最终打包,将打包之后的项目移至 Flutter Web 的项目中。

关键点如下:

window自定义声明:

declare global {
    interface Window {
        toastMsg: Function;
    }
}

关键方法:

const getAddress = async () => {
    // ...
    // 网络请求
    // ...
    const  ads = "请求结果";
    setAddress(ads);

    if (typeof window["toastMsg"] === "function") {
        window.toastMsg(address);
    }

    return address ? address : "未登录";
};

// 提供给 Flutter 的方法
window["getMyAddress"] = async () => {
    return await getAddress();
};

2. 将 React 打包,把关键信息复制到 Flutter Web 项目中

2.1 React 打包

2.2 将这些文件复制

2.3 将关键文件复制到 Flutter 项目

2.4 在 Flutter 中调用方法

@JS()
external getMyAddress();
// 暴露给JS的方法
void toastMsg(String msg) {
  print("address: $msg");
  MyUtils.showToast(msg);
}

Widget buildMine() {
  return Container(
    child: Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        TextButton(
          onPressed: () {
            // 将方法暴露给 js 的 window
            js.context["toastMsg"] = toastMsg;

            // 调用 JS 方法
            var personInfo = js.context.callMethod('getMyAddress');
            print("getAddress is $personInfo");
          },
          child: Text("js2PersonInfo"),
        ),
        SizedBox(height: 20),
        TextButton(
          onPressed: () async {
            // 调用Js的方法
            try {
              var promise = getMyAddress();
              var result = await promiseToFuture(promise); // 第三个坑
              print("getAddress is $result");
            } catch (e) {
              print("getDeviceInfo错误信息是 $e");
            }
          },
          child: Text("getMyAddress"),
        ),
        SizedBox(height: 20),
      ],
    ),
  );
}

注意:

至此,就实现了 Flutter Web 与 React 的交互。列出关键点记录,以便后续使用。


不仅单单是交互。

以此方式,还可以弥补一些 Flutter 非常大的一个劣势:网页首次打开,非常缓慢。

可以使用 React 实现一些动画,或者加载初始的界面,Flutter也会在同步加载。

结束。

如果有什么错误,或者有更好的实现方式,欢迎讨论。

参考:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容