Flutter之使用Webview与Vue项目通信

3,866 阅读1分钟

1. flutter webview插件选择

目前flutter的webview常用库有flutter_webview_pluginswebview_flutter,这里我选择的是webview_flutter

理由:webview_flutter是官方维护的插件,而且通过实践发现,webview_flutter与原生组件嵌套结合更友好,再一个我发现使用flutter_webview_plugins加载webview后在IOS端无法使用手势侧滑返回上一页

所以我选择webview_flutter来加载网页

2. 引入webview_flutter

// 在pubspec.yaml中添加依赖
webview_flutter: 0.3.22+1

// 在需要的地方导入包
import 'package:webview_flutter/webview_flutter.dart';

// 在iOS,需要在info.plist中添加
<key>io.flutter.embedded_views_preview</key>
<string>YES</string>

3. flutter的webview如何与js交互

final Completer<WebViewController> _webController = Completer<WebViewController>();

@override
Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: <Widget>[
            WebView(
                // h5页面的地址
                initialUrl: 'https://test.com/article-detail.html',
                // JS执行模式, 允许JS执行
                javascriptMode: JavascriptMode.unrestricted,
                // hh5可以根据navigator.userAgent判断当前环境
                userAgent: 'FlutterApp',
                // 在WebView创建完成后调用,只会被调用一次
                onWebViewCreated: (WebViewController webController) { 
                    // 获取到WebViewController实例
                    _webController.complete(webController);
                },
        
                // WebView加载完毕时的回调
                onPageFinished: (String url) {
                    // flutter调用js
                    _webController.future.then((controller){
                        var name = 'test'; // 方法名
                        var data = 'hello'; // 传递的参数
                        controller.evaluateJavascript("$name('$data')");
                    });
                },
                  
                // js调用flutter
                javascriptChannels: <JavascriptChannel>[
                    JavascriptChannel(
                        name: 'hide_loading', // 需要与h5一致
                        onMessageReceived: (JavascriptMessage msg) {
                            // print("参数: ${msg.message}");
                            // 关闭骨架屏加载效果
                            setState(() {
                                loading = false;
                            });
                        }
                    ),
                ].toSet(),
            ),
                
            // 骨架屏加载
            Visibility(
              visible: loading,
              child: SkeletonPage()
            )
        ]
      );
    );
}
  • 上面我们在 Flutter 端通过 WebViewController 的 evaluateJavascript 方法进行js的调用,js方法名为test,同时传递参数hello,参数只能是字符串类型(h5调flutter传递参数也只能是字符串)
// 定义js方法给flutter调用
<script>
    function test(param) {
        console.log(param) // 'hello'
    }
</script>
// js调用flutter
<button onclick="hideLoading">关闭loading</button>

<script>
    function hideLoading() {
        window['hide_loading'].postMessage('hello')
    }
</script>

4. 关键点,在vue里面,需要把方法暴露给window,这样flutter才能调用

mounted() {
    window.test = this.test
}

methods: {
    test(param) {
        console.log(param) // 'hello'
    }
}