uniapp各端通过webview实现互相通信

目前网上,包括官方文档针对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,

}"设置宽高都不起作用

相关推荐
白远山11 小时前
上海24小时自助健身房系统软件开发实战指南:从需求到部署
java·架构·uni-app·需求分析
海鸥两三17 小时前
小程序文档预览 · 进阶面试题
小程序·uni-app·uniapp
海鸥两三17 小时前
微信小程序 PDF 预览实践(uni.downloadFile → uni.openDocument)
小程序·uni-app
PedroQue991 天前
uni-app x 事件通信插件重磅上线
前端·uni-app
gnip2 天前
uni-app 原生插件
前端·javascript·uni-app
白远山3 天前
自助健身小程序源码:架构拆解、核心链路与本地部署实战
java·架构·uni-app·需求分析
2501_915909063 天前
怎么用 FlutterFlow 把应用发布到 App Store?
android·ios·小程序·https·uni-app·iphone·webview
2501_915918414 天前
怎么把 Python 写的 Flet 应用打包成 iOS App 并上架 App Store?
android·ios·小程序·https·uni-app·iphone·webview
Geek_Vison4 天前
小程序容器如何抹平系统差异,让一个小程序运行在 iOS、安卓、鸿蒙和电脑端
小程序·uni-app·harmonyos·mpaas
PedroQue994 天前
0.5.0重磅发布:动画插件+H5体验全面优化
前端·uni-app