本篇只是上篇的补充

介绍一些当前的 flutter_web 版和 flutter 的移动版的差别

dart:io 包无法使用造成的影响

dart:io是一个在 flutter 中常用的包,但是在 web 版中是使用不了的

dio 不能用

dio包用不了,因为 dio 包是依托于 dart:io 包中的 HttpClient 进行的封装

并且因为国内很多初学者朋友人云亦云的选择了 dio 作为 http 的请求框架,所以今后如果有打算想要做 flutter_web 版的朋友可能现在就要考虑一下 dio 的使用问题了

当然 dio 包今后也可以迁移底层访问库为http,再进行二次封装形成 dio_with_http 那就是另一个故事了

另外 web 中的 http 请求可以使用 dart:html 中的 HttpRequest

使用http库的访问如下:

import 'package:http/http.dart' as http;
Widget fromHttp() {
    return FutureBuilder<http.Response>(
      future: http.get("https://api.github.com/"),
      builder: (BuildContext context, snapshot) {
        if (!snapshot.hasData) {
          return Container();
        }
        var body = snapshot.data.body;
        return Text(body);
      },
    );
  }

以上的代码反馈回来是这样的 20190513150611.png

使用 HttpRequest:

import 'dart:html' as html;

Widget buildWithHttpRequest() {
    var req = html.HttpRequest.getString("https://api.github.com/");
    return FutureBuilder<String>(
      future: req,
      builder: (BuildContext context, snapshot) {
        if (!snapshot.hasData) {
          return Container();
        }
        var body = snapshot.data;
        return Column(
          children: <Widget>[
            Text("使用 HttpRequest 访问的 api"),
            Text(body),
          ],
        );
      },
    );
  }

截图是这样的

20190514091204.png


在 flutter_web 浏览器中需要注意的一点是, 无论你使用什么访问框架来访问 http,都会遇到跨域的问题, 跨域问题是一个经典的web前端开发问题, 搜索引擎中的解决方案和完善的说明有很多, 请自行理解

File 相关的 api 无法使用

在 flutter 移动版中,经常会遇到需要使用 File 来操作文件的情况,下载/读取文件都需要 File 的支持

Socket/WebSocket

前面说了 HttpClient 不能用,io 包中还包含 Socket/Websocket, 它们都是 dart:io 的类, 所以都无法使用

dart:html 包的使用

虽然不建议使用,但是这东西在 flutter_web 中是可用的

比如,我修改 web/index.html, 添加一个h1标签

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title></title>
    <script defer src="main.dart.js" type="application/javascript"></script>
  </head>
  <body>
    <h1 id="tmpId" style="float: left;position: fixed;z-index: 100;">你好</h1>
  </body>
</html>

然后重新运行代码,得到的是这样的

20190513164555.png

接着修改 dart 文件, 引入 html 包

import 'dart:html' as html;

  _buildHtmlFunWidget() {
    return FlatButton(
      child: Text("操作html元素"),
      onPressed: () {
        var e = html.window.document.getElementById("tmpId");
        e.text = this.counter.toString();
      },
    );
  }

这样就可以像传统的 js 一样操作 dom 元素, 然后将数字设置为当前的数字 Kapture 2019-05-13 at 16.49.06.gif 关于这个包的具体使用请查看 html 包的注释/文档

这里是一个简单的使用说明 https://dart.dev/tutorials/web/low-level-html/connect-dart-html

js 包的使用

官方说明

pub 地址

lib.js 文件:

function addNumbers(a, b) {
  return a + b;
}

function getFromJS() {
  return '我是从js来的字符串';
}

引入 js 文件

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title></title>
    <script src="assets/lib.js"></script>
    <script defer src="main.dart.js" type="application/javascript"></script>
  </head>
  <body>
    <h1 id="tmpId" style="float: left;position: fixed;z-index: 100;">你好</h1>
  </body>
</html>

dart 文件

@JS()
library lib;

import 'package:js/js.dart';

@JS()
external String getFromJS();

@JS()
external num addNumbers(num a, num b);

void add1And2() {
  print(addNumbers(1, 2));
}

String getJS() {
  return getFromJS();
}

dart 文件需要注意一点, 外部直接调用getFromJS方法,addNumbers方法会报错, 需要封装一层 dart 方法

dart 的 widget

  _callJSMethodWidget() {
    return FlatButton(
      child: Text("点击"),
      onPressed: () {
        add1And2();
        // print(getFromJS());
        print(getJS());
      },
    );
  }

这样点击这个按钮后可以看到

20190513174110.png

结尾

本篇粗略介绍了一些上篇没有介绍完整的东西

仓库和上一篇相同: 查看 example/helloworld 目录

以上