『uni-app』web-view 大量数据通信

2022-09-23 09:50:38 浏览数 (2)

本文简介

点赞 关注 收藏 = 学会了

uni-app 或者 微信小程序 中,都有 web-view 组件。

该组件是一个浏览器组件,可以承载网页的内容。而且该组件是全屏的,会覆盖该组件之外的其他内容。

本文要讲解在 uni-app 中使用 web-view 怎么实现大量数据通信。

我所使用的是 Vue 3 语法。

web-view 数据通信方法

web-view 文档

web-view 其实有点像 iframe ,但在 uni-app 又提供了几种基础的通信方式。

基础用法可以看文档,本文主要讲解如何在 主应用web-view 传输数据。

本案例目录结构

代码语言:javascript复制
省略部分目录

- hybrid
|- html
 |- js
  |- uni.webview.1.5.3.js
 |-index.html
- pages
 |- index
  |- index.vue

父传子

我们暂定,主应用web-view 的页面为

“父传子” 的方式有2种:

  1. 通过 url 传值
  2. 使用 uni.webview.js

1、通过 url 传值

数据量少的话,可以通过 url 的方式传给子应用。

index.vue

代码语言:javascript复制
<template>
  <view class="content">
    <web-view
        src="/hybrid/html/index.html?msg=hello"
    ></web-view>
  </view>
</template>

这种方法的优点是简单,缺点是传输的数据量有限,而且基本传输的都是字符串。

2、使用 uni.webview.js 传值

本文使用的是 uni.webview.1.5.3.js ,在阅读本文时可能官方已经更新了新版。

你可以在 web-view 文档 里,滑到“注意事项”里面找到最新版的下载地址

主应用 /pages/index/index.vue

代码语言:javascript复制
<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

代码语言:javascript复制
<!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

代码语言:javascript复制
<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

代码语言:javascript复制
<!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

以上官方提供的方法和属性建议你都尝试一遍,都是非常简单的。

0 人点赞