目前网上,包括官方文档针对uniapp的webview的内容都是基于vue2的,此文章基于vue3的composition API方式
网页对网页
由于uniapp中的webview只支持引入h5页面,不支持互相通信,所以要条件编译,用iframe导入页面,并通信
父页面
<!-- #ifdef H5 --> <iframe src="http://192.168.0.105:5000/#/index" border="none" width="100%" height="100vh" frameborder="0" style="border: none; height: calc(100vh - 8px)" ref="iframe" @load="handlePageLoaded" ></iframe> <!-- #endif --> const iframe = ref() const handlePageLoaded = () => { console.log('h5端网页加载成功') iframe.value.contentWindow.postMessage( { type: 'Function', // 调用方法 from: 'uniapp', functionName: 'appCallback', params: { from: 'uniapp h5', }, }, '*', ) // 需指定子页面域名 // 调用子页面全局方法(同源才行) // iframe.value.contentWindow.appCallback({ name: 'tom' }) } // #ifdef H5 // 监听子页面的返回结果 window.addEventListener('message', function (event) { if (event.data?.from == 'h5') { console.log('uniapp收到iframe发来消息', event.data) } }) // #endif
子页面
window.addEventListener('load', function () { console.log('子页面(被iframe嵌入)所有资源加载完成!'); // 这里可以执行加载完成后的操作(如初始化、发送消息给父页面等) }); window.addEventListener('message', function (event) { // 验证消息来源 if (event.data?.from == 'uniapp') { const message = event.data; event.source.postMessage({ type: 'functionResult', from: 'h5' }, event.origin); if (message.functionName) { window[message.functionName](message.params || {}) } console.log('iframe收到uniapp消息', message) } });
网页对app或者小程序
子页面
引入uniapp官方文档提供的js文件
<script src="/lib/uni.webview.js"></script> // 待触发 `UniAppJSBridgeReady` 事件后,即可调用 uni 的 API。 document.addEventListener('UniAppJSBridgeReady', function () { console.log('uniapp中webview加载完成') uni.getEnv(function (res) { console.log('当前环境:' + JSON.stringify(res)); setTimeout(() => { if (res.h5) { // uniapp不支持h5之间用webview互相通信 } else if (res.plus) { uni.postMessage({ data: { action: 'message', other: { name: 'ike', age: 30 } } }); } }, 200) }); // 发送消息 // uni.postMessage({ // data: { // action: 'message' // } // }); });
父应用
import { onReady } from '@dcloudio/uni-app' import { getCurrentInstance } from 'vue' const wv = ref() onReady(() => { // #ifndef H5 setTimeout(() => { wv.value = instance?.proxy.$scope.$getAppWebview().children()[0] }, 100) // #endif }) const handleWVMessage = (ev: any) => { console.log('收到web消息', ev.detail.data) wv.value.evalJS(`appCallback({action: 'message', data: {name: 'tom'}})`) }
目前存在问题
1、app端无法使用load监听网页是否加载完成,小程序端可以
2、页面ready后,要延时一阵才能拿到真正的webview实例,所以网页端监听到加载完毕,也要延时一阵再给uniapp发消息
3、app端通过
:webview-styles="{
process: false,
width: '50%',
height: props.height,
}"设置宽高都不起作用