一、项目背景:
原项目:Cordova + vue(H5)
现项目:Uniapp + vue(H5)
二、问题:
Uniapp作为Cordova的替代,则以前Cordova的插件,例如调用摄像头扫码,这种接口需要重写。
由于H5的环境和APP的环境是两个天然隔离的运行环境,所以通过常规的手段是不能互相通信的。
三、解决方法:
1、App前提条件,在app写绑定事件。
在app方面的代码如下,webView是用来承载H5内容的
<web-view :src="data.uri" @message="getMessageFromH5($event)"></web-view>
@message绑定的事件如下,下图为vue3的写法
@message在h5向app发送消息时,触发。
function getMessageFromH5(e) {
console.log("【H5 => APP】"+ JSON.stringify(e.detail.data));
}
2、H5前提条件,在vue里的index.html文件里,使用原生监听,去监听一个事件,
首先需要到uniapp官网去下载一个JSBridge(一个JS文件),通过它,H5能使用一个至关重要
的方法,uni.postMessage(),点击 JSBridge桥 下载。
下载完了之后,得到一个js文件,这个js文件怎么加载到H5中使用呢,引入方式如下
<script type="text/javascript" src="./uni.webview.1.5.3.js"></script>
在index.html中,在新写一个<script>标签对,将下面代码放入。
document.addEventListener('UniAppJSBridgeReady', function() {
console.log('jsb 已经加载完成,现在可以通信了!')
})
此时,两边的互相通信的准备工作就已经做好了,请继续往下,查看如何发送消息,另一端接收。
3、App向H5进行通信:
在APP给web-view打上标签,ref的使用,请参考vue文档,用来获取组件实例,类似于js里id
<web-view ref="webview" :src="data.uri" @message="getMessageFromH5($event)"></web-view>
在H5里打印接收的消息,此处写了一个方法,等待调用
document.addEventListener('UniAppJSBridgeReady', function() {
console.log('js已经完成加载')
})
// 记住这个函数名字
function getMessageCallback() {
console.info('【APP => H5】'+ JSON.stringify($event))
}
什么?竟然要在app里去调用H5身上的方法?是的! )
function sendMessageToH5(msg) {
let func = "getMessageCallback("+JSON.stringify(msg)+")"; // 此demo固定写法
const pages = getCurrentPages(); // 获取App当前的展示的界面
this.webview = pages[pages.length - 1].$getAppWebview().children()[0];
this.webview.evalJS(func);
}
然后查看控制台,是否有打印。
4、H5向App进行通信:
uni.postMessage({
data: {
action: 'postMessage'
}
});
需要注意的是,这个uni这个东西,在jsbridge上的,所以一定要保证该js在一上来就加载完成了, 然后加载完成之后呢,在vue2(h5)的任何地方调用uni.postMessage都可以向app发送消息了。
至于APP的接收嘛。
1、前提条件
这里就不重复贴代码了,自己往上翻吧。
============= 另外贴一个Demo ==========
gitee:UniappEachSendMessageWithHtml: uniapp与常规的html5通信,Demo仅使用Vue构建