点赞 + 关注 + 收藏 = 学会了
在 uni-app
或者 微信小程序
中,都有 web-view
组件。
该组件是一个浏览器组件,可以承载网页的内容。而且该组件是全屏的,会覆盖该组件之外的其他内容。
本文要讲解在 uni-app
中使用 web-view
怎么实现大量数据通信。
我所使用的是 Vue 3
语法。
web-view 文档
web-view
其实有点像 iframe
,但在 uni-app
又提供了几种基础的通信方式。
基础用法可以看文档,本文主要讲解如何在 主应用 向 web-view 传输数据。
本案例目录结构
省略部分目录 - hybrid |- html |- js |- uni.webview.1.5.3.js |-index.html - pages |- index |- index.vue
我们暂定,主应用 为 父,web-view
的页面为 子 。
“父传子” 的方式有2种:
url
传值uni.webview.js
数据量少的话,可以通过 url
的方式传给子应用。
index.vue
<template> <view class="content"> <web-view src="/hybrid/html/index.html?msg=hello" ></web-view> </view> </template>
这种方法的优点是简单,缺点是传输的数据量有限,而且基本传输的都是字符串。
本文使用的是 uni.webview.1.5.3.js
,在阅读本文时可能官方已经更新了新版。
你可以在 web-view 文档 里,滑到“注意事项”里面找到最新版的下载地址
主应用 /pages/index/index.vue
<template> <view class="content"> <web-view ref="webview" src="/hybrid/html/index.html" @message="handleMessage" ></web-view> </view> </template> <script setup> import { ref } from 'vue' import { onLoad } from '@dcloudio/uni-app' const webview = ref(null) const pages = getCurrentPages() const vw = ref(null) // 获取子应用 function getVw() { // 找到路由栈里的最后一位 vw.value = pages[pages.length - 1].$getAppWebview().children()[0] // 使用 evalJS 方法,调用子应用里的事件 // receiveData 是在子应用里定义的事件 // 最后需要注意,evalJS 传入的是一个字符串。 vw.value.evalJS("receiveData({msg: '雷猴啊'})") } onLoad(() => { // 如果是页面初始化调用时,需要延时一下 setTimeout(() => { getVw() }, 1000) }) </script>
子应用 /hybrid/html/index.html
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>web-view</title> </head> <body> <!-- 引入 uni.webview.js --> <script src="./js/uni.webview.1.5.3.js"></script> <script> // 接收外层传进来的数据 function receiveData(data) { console.log(JSON.stringify(data)) } </script> </body> </html>
这么简单就实现了大量数据的传输,而且还可以传对象等数据。
最后需要注意的是,子应用定义接收数据的方法名,要跟主应用调用时一致。
比如本例定义的方法名为 receiveData
。
子应用要向主应用传值,uni-app
官方就提供了方法 @message
。
主应用 /pages/index/index.vue
<template> <view class="content"> <web-view src="/hybrid/html/index.html" @message="handleMessage" ></web-view> </view> </template> <script setup> import { ref } from 'vue' // 接受 webview 传递过来的数据 function handleMessage(msg) { console.log(msg) } </script>
子应用 /hybrid/html/index.html
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>web-view</title> </head> <body> <div> <button onclick="handleClick()">向上传递数据</button> </div> <script src="./js/uni.webview.1.5.3.js"></script> <script> // 向外传递数据,数据要放在data里 function handleClick () { uni.postMessage({ data: { msg: '雷猴' } }) } </script> </body> </html>
此时在页面上点击按钮,主应用就会接收到子应用传过来的数据。
除了 @message
外,uni-app
还提供了很多方法和属性可以调用。
方法
方法名 | 说明 | 平台差异说明 |
---|---|---|
uni.navigateTo | navigateTo | |
uni.redirectTo | redirectTo | |
uni.reLaunch | reLaunch | |
uni.switchTab | switchTab | |
uni.navigateBack | navigateBack | |
uni.postMessage | 向应用发送消息 | 字节跳动小程序不支持、H5 暂不支持(可以直接使用 window.postMessage (opens new window)) |
uni.getEnv | 获取当前环境 | 字节跳动小程序与飞书小程序不支持 |
属性
属性名 | 类型 | 说明 | 平台差异说明 |
---|---|---|---|
src | String | webview 指向网页的链接 | |
allow | String | 用于为 iframe (opens new window)指定其特征策略(opens new window) | H5 |
sandbox | String | 该属性对呈现在 iframe (opens new window)框架中的内容启用一些额外的限制条件。 | H5 |
webview-styles | Object | webview 的样式 | App-vue |
update-title | Boolean | 是否自动更新当前页面标题。默认值:true |
App-vue (HBuilder X 3.3.8+) |
@message | EventHandler | 网页向应用 postMessage 时,会在特定时机(后退、组件销毁、分享)触发并收到消息。 |
H5 暂不支持(可以直接使用 window.postMessage (opens new window)) |
@onPostMessage | EventHandler | 网页向应用实时 postMessage |
App-nvue |
以上官方提供的方法和属性建议你都尝试一遍,都是非常简单的。