当前位置:首页 » 《资源分享》 » 正文

uniapp实现与webview之间的相互通讯

19 人参与  2024年10月16日 14:01  分类 : 《资源分享》  评论

点击全文阅读


基于uniapp开发在一些特殊场景,可能会用到app嵌套h5或h5嵌套h5的场景,uniapp中有一个web-view组件类似于iframe我们可以基于web-view实现双向通信,以下是对不同情况下的使用总结:

写在最前面:

uniapp开发的app嵌套h5时必须是.nvue文件否则没有这个sWebViewRef.value.evalJs函数uni.webview.js只需要在嵌套的h5中引入

情况一:app嵌套h5(app、h5均用uniapp开发)

在正式使用前要先在嵌套的h5中中引入uni.webview.1.5.6.js以1.5.6举例,文件可能已更新,最新请移步uni.webview.js 最新版地址下载

下载完成后,我们只需要在h5项目main.js中进行引入

// main.jsimport './uni_web_view_1.5.6.js'

引入完成后我们在h5项目中任意文件下打印uni会发现在uni上多了一个webView,打印uni.webView会发现他是一个对象,并有如下方法:

navigateBack、navigateTo、reLaunch、redirectTo、switchTab、getEnv、postMessage

上述方法相信作为uni开发者大家并不陌生,这里只着重讲解:getEnv、postMessage

h5向app发送消息

<!-- h5 --><template>   <button @click="postMsg">向应用发送信息</button></template><script setup>  // getEnv 获取当前环境  uni.webView.getEnv((res) => {    console.log('当前环境:' + JSON.stringify(res));  })  // postMessage 向应用发送消息  const postMsg = () => {    uni.webView.postMessage({      data: {        msg: '哈哈哈',      },    })  }</script><!-- h5通过postMessage像app发送信息,app如何接收?创建.nvue文件,并编写如下代码: --><!-- app --><template>  <web-view ref="sWebViewRef" id="sWebView" :style="webviewStyles" :src="url" @onPostMessage="handleWebViewMessage" @message="handleWebViewMessage">  </web-view></template><script setup>  import { ref, onMounted } from 'vue'  // nvue文件不能使用100vw,100vh  const systemInfo = uni.getSystemInfoSync()  const webviewStyles = ref({    width: '',    height: '',  })  webviewStyles.value.width = systemInfo.windowWidth + 'px'  webviewStyles.value.height = systemInfo.windowHeight + 'px'  const sWebViewRef = ref()  // h5地址,这里临时写死实际项目自行根据环境判断  const url = ref('http://192.168.110.128:7189/')  // 接收内容:  const handleWebViewMessage = (event) => {    console.log('handleWebViewMessage', event)    const [noWEBData] = event.detail.data    console.log('noWEBData', noWEBData)  }</script>

上面我们实现了在h5中向app中发送信息,那app如何向h5中发送信息呢?

<!-- app --><template>  <web-view ref="sWebViewRef" id="sWebView" :style="webviewStyles" :src="url" @onPostMessage="handleWebViewMessage" @message="handleWebViewMessage">  </web-view></template><script setup>  import { ref, onMounted } from 'vue'  const sWebViewRef = ref()  // h5地址,这里临时写死实际项目自行根据环境判断  const url = ref('http://192.168.110.128:7189/')  // 接收内容:  const handleWebViewMessage = (event) => {    console.log('handleWebViewMessage', event)    const [noWEBData] = event.detail.data    console.log('noWEBData', noWEBData)  }  const test = ref('嘻嘻嘻')  onMounted(() => {    setInterval(() => {      sWebViewRef.value.evalJs(`x_sun('${test.value}')`)    }, 2000)  })</script><!-- h5 --><template>   <button @click="postMsg">向应用发送信息</button></template><script setup>  // getEnv 获取当前环境  uni.webView.getEnv((res) => {    console.log('当前环境:' + JSON.stringify(res));  })  // postMessage 向应用发送消息  const postMsg = () => {    uni.webView.postMessage({      data: {        msg: '哈哈哈',      },    })  }  window.x_sun = (e) => {    console.log('x_sun', e)  }</script>

情况二:app嵌套h5(h5用vue或react开发)

上述情况一中讲到了要引用uni.webview,在这里我默认你已经看了如何在嵌套h5中引入uni.webview.js

引入完成后我们在h5项目中任意文件下打印uni会发现他是一个对象,并有如下方法:

navigateBack、navigateTo、reLaunch、redirectTo、switchTab、getEnv、postMessage

上述方法在情况一中已有案例便不再复述

情况三:h5嵌套h5(均用uniapp开发)

为了方便理解我将外层h5称之为父级,嵌套的内层h5称之为子级

上述情况一中讲到了要引用uni.webview,在这里我默认你已经看了如何在嵌套h5中引入uni.webview.js

引入完成后我们在h5项目中任意文件下打印uni会发现他是一个对象,并有如下方法:

navigateBack、navigateTo、reLaunch、redirectTo、switchTab、getEnv、postMessage

子级h5向父级h5发送消息

<!-- 子级h5 --><template>   <button @click="postMsg">向父级发送信息</button></template><script setup>  // getEnv 获取当前环境  uni.getEnv((res) => {    console.log('当前环境:' + JSON.stringify(res));  })  // postMessage 向父级发送消息  const postMsg = () => {    uni.postMessage({      data: {        msg: '哈哈哈',      },    })  }</script><!-- 子级通过postMessage向父级发送信息,父级如何接收? --><!-- 父级h5 --><template>  <web-view ref="sWebViewRef" id="sWebView" :style="webviewStyles" :src="url" @onPostMessage="handleWebViewMessage" @message="handleWebViewMessage">  </web-view></template><script setup>  import { ref, onMounted } from 'vue'  // nvue文件不能使用100vw,100vh  const systemInfo = uni.getSystemInfoSync()  const webviewStyles = ref({    width: '',    height: '',  })  webviewStyles.value.width = systemInfo.windowWidth + 'px'  webviewStyles.value.height = systemInfo.windowHeight + 'px'  const sWebViewRef = ref()  // h5地址,这里临时写死实际项目自行根据环境判断  const url = ref('http://192.168.110.128:7189/')  // 接收内容:  const handleWebViewMessage = (event) => {    console.log('handleWebViewMessage', event)    const { data: webData } = event.data    console.log('webData', webData)  }  // h5通过对message添加侦听事件,监听嵌套h5中发送的内容  window.addEventListener('message', handleWebViewMessage)</script>

上面我们实现了在子级h5中向父级h5中发送信息,那父级h5如何向子级h5中发送信息呢?

<!-- 父级h5 --><template>  <web-view ref="sWebViewRef" id="sWebView" :style="webviewStyles" :src="url" @onPostMessage="handleWebViewMessage" @message="handleWebViewMessage">  </web-view></template><script setup>  import { ref, onMounted } from 'vue'  const sWebViewRef = ref()  // h5地址,这里临时写死实际项目自行根据环境判断  const url = ref('http://192.168.110.128:7189/')  // 接收内容:  const handleWebViewMessage = (event) => {    console.log('handleWebViewMessage', event)    const [noWEBData] = event.detail.data    console.log('noWEBData', noWEBData)  }  const test = ref('嘻嘻嘻')  const sWebViewEl  = ref()  onMounted(() => {    sWebViewEl.value = document.getElementById('sWebView').contentWindow    setInterval(() => {      sWebViewEl.contentWindow.postMessage({ fn: 'x_sun', arg: test.value }, '*')      // 也可手动指定我要向这个子级发送信息      // sWebViewEl.contentWindow.postMessage({ fn: 'x_sun', arg: test.value }, 'http://192.168.110.128:7189')    }, 2000)  })</script><!-- 子级h5 --><template>   <button @click="postMsg">向应用发送信息</button></template><script setup>  // getEnv 获取当前环境  uni.webView.getEnv((res) => {    console.log('当前环境:' + JSON.stringify(res));  })  // postMessage 向应用发送消息  const postMsg = () => {    uni.webView.postMessage({      data: {        msg: '哈哈哈',      },    })  }  window.x_sun = (e) => {    console.log('x_sun', e)  }  const handleWebViewMessage = (event) => {   event.data.fn && window[event.data.fn](event.data.arg)  }  window.addEventListener('message', handleWebViewMessage)</script>

如若需要既需要兼容app嵌套h5又需要兼容h5嵌套h5可以在父级的app或h5页面中通过uniapp中的条件编译进行判断,参考代码:

<script setup>  import { ref, onMounted } from 'vue'  import { useWebView } from './hooks/useWebView'  import { useNoWebView } from './hooks/useNoWebView'  const { webMessageMap } = useWebView()  const { noWebMessageMap } = useNoWebView()  const sWebViewRef = ref()  const url = ref('http://192.168.110.128:7189/')  const systemInfo = uni.getSystemInfoSync()  const webviewStyles = ref({    width: '',    height: '',  })  webviewStyles.value.width = systemInfo.windowWidth + 'px'  webviewStyles.value.height = systemInfo.windowHeight + 'px'  const handleWebViewMessage = (event) => {    // #ifdef WEB    const { data: webData } = event.data    webData?.name && (webMessageMap[webData.name] ? webMessageMap[webData.name](webData.arg) : webMessageMap.default(webData.arg))    // #endif    // #ifndef WEB    const [noWEBData] = event.detail.data    console.log('noWEBData', noWEBData)    noWebMessageMap[event.type] ? noWebMessageMap[event.type](noWEBData) : noWebMessageMap.default(noWEBData)    // #endif  }  const test = ref('嘻嘻嘻')  const sWebViewEl = ref()  // #ifdef WEB  onMounted(() => {    sWebViewEl.value = document.getElementById('sWebView').contentWindow    setInterval(() => {      sWebViewEl.value.postMessage({ fn: 'x_sun', arg: test.value }, '*')      // sWebViewEl.contentWindow.postMessage({ name: 'x_sun', arg: test.value }, 'http://192.168.110.128:7189')    }, 2000)  })  // #endif  // #ifndef WEB  onMounted(() => {    setInterval(() => {      sWebViewRef.value.evalJs(`x_sun('${test.value}')`)    }, 2000)  })  // #endif  // #ifdef WEB  window.addEventListener('message', handleWebViewMessage)  // #endif</script><template>  <view>    <web-view ref="sWebViewRef" id="sWebView" :style="webviewStyles" :src="url" @onPostMessage="handleWebViewMessage" @message="handleWebViewMessage">    </web-view>  </view></template><style></style>

参考文献:

web-view | uni-app官网

在web-view加载的本地及远程HTML中调用uni的API及网页和vue页面通讯


点击全文阅读


本文链接:http://zhangshiyu.com/post/172608.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1