uni-app使用html5+创建webview,可以控制窗口大小、显隐、与uni通信

最近使用 uni-app 开发安卓端的 App,因为要嵌入一个原本已经开发完的系统,打算使用 web-view 的方式进行嵌入。

因为项目工期比较紧,所以是两个前端并行开发,最后再合到一起。

结果就是这个过程中出问题了...

需求

需求方面是:

A同学负责通讯方面的工作,所以页面应该在首页加载的时候就被挂载上去,这样一来启动系统的时候就注册了通讯模块,不影响收发信息。

B同学负责其他部分,在首页展示系统内部的统计数据,可以算是一个安卓端的简易大屏。

原本A同学的方案是在系统页面上创建一个 web-view,然后嵌入系统。这样一来也不影响B同学开发新系统。

问题

结果整合代码的时候才发现,web-view标签 是自动铺满整个页面 的,而且是无法隐藏的。

这就尴尬了,App进来以后直接看到的就是 A同学的通讯页面,无法看到B同学的大屏了。

问题抛到了我手里,我经过一番简单的调研,再加上一顿猛如虎的操作,又通过 Trae 一顿AI,最后回复他们说:无解

对此 Trae 给出的原因是:uni-app 中内置的 web-view 标签本身没有隐藏的API,在 web-view 标签外增加 view 标签,绑定 v-show 方法不生效。

只能绑定 v-if 生效,但是绑定 v-if=false 的时候相当于 web-view 直接被销毁了,会导致通讯模块收不到信息。

解决

好在天无绝人之路,uni-app 官方文档中表示:在 html5+ 中其实存在 web-view 的 API,能够操作窗口的大小。

那么既然能够操作窗口的大小,肯定也能够控制显隐。

于是乎我使用 Trae 让他使用 html5+ 中的 create 方法创建 web-view,并给出完整的解决方案。

js 复制代码
createWebView() {
    let that = this;
    if (this.webviewIns) return;

    this.webviewIns = plus.webview.create(
        'http://192.168.25.110',
        '1008610010' // ID(必须唯一)
        {
            top: '24px',
            bottom: '0px',
            width: '300px',
            height: '600px',
            scrollIndicator: 'none',
            scalable: false
        }
    );

    // 设置页面默认隐藏
    this.webviewIns.hide();
}

这时候已经成功创建了 web-view 并且处于隐藏状态,不耽误传参。

但是又遇到了一个问题,web-view无法与uni-app通信

Trae 先给出了 uni-app 官方提供的方法,使用 uni.postMessage 方法,但是在通讯系统中插入了这个方法以后,不报错,并且显示发送消息成功,但uni-app 这边却无法接收到。

Trae 又使用 evalJS 方法插入相应的脚本,但是也没有反应。同样是发送成功,但是接收不到。


两种方案均不可用,我又详细看了看 uni-app 的官方文档,让 Trae 分析 web-view 标签上绑定的 @message 方法应该是经过特殊封装的,能够捕获到 view-view 内使用 uni.postMessage 方法发送的数据。

Trae给出的解释是:由于我现在使用 plus.web-view.create 创建窗口,绕过了uni-app 所以即便是绑定 message 也无效了。

所以采用 html+ 原生方法发送数据,在 web-view 中使用 plus.webview.postMessageToUniNView 方法发送数据。

在 uni-app 端使用 plus.globalEvent.addEventListener 接收数据。

js 复制代码
// 发送数据
pushMessage() {
    plus.webview.postMessageToUniNView({
        type: 'tpUniAPP',
        args: {
            args1: 'test123'
        }
    }, '__uniapp__service');
}

接收数据方法写在 createWebView 方法内。

js 复制代码
// 接收数据
createWebView() {
    let that = this;
    if (this.webviewIns) return;

    // 创建一个新的 WebView
    this.webviewIns = plus.webview.create(
        ...
    );
    
    // web-view加载完成
    this.webviewIns.addEventListener('loaded', () => {
        plus.globalEvent.addEventListener('plusMessage', (message)=>{
            let data = message?.data?.args?.data;
            if(data?.name === 'postMessage') {
                if (data?.arg?.type === 'show') {
                    // 显示
                    that.webviewIns.show();
                }
                if (data?.arg?.type === 'hide') {
                    // 隐藏
                    that.webviewIns.hide();
                }
            }
        })
    });
    
    this.webviewIns.hide();
},

结论

目前主要解决了两个问题:

  1. web-view 大小、显隐不可控问题。
  2. web-view 与 uni-app 通信问题。

发送数据方法可以卸载 Pinia 的公共方法中,或者使用 EventBus,统一处理。

Ps: 第二个问题解决方案不是太优雅,如果有兄弟有更好的方案可以分享一下。

相关推荐
行走的陀螺仪36 分钟前
uni-app + Vue3编辑页/新增页面给列表页传参
前端·vue.js·uni-app
We་ct2 小时前
LeetCode 205. 同构字符串:解题思路+代码优化全解析
前端·算法·leetcode·typescript
2301_812731412 小时前
CSS3笔记
前端·笔记·css3
ziblog2 小时前
CSS3白云飘动动画特效
前端·css·css3
越努力越幸运5082 小时前
CSS3学习之网格布局grid
前端·学习·css3
半斤鸡胗2 小时前
css3基础
前端·css
ziblog2 小时前
CSS3创意精美页面过渡动画效果
前端·css·css3
akangznl2 小时前
第四章 初识css3
前端·css·css3·html5
会豪2 小时前
深入理解 CSS3 滤镜(filter):从基础到实战进阶
前端·css·css3
头顶一只喵喵2 小时前
CSS3进阶知识:CSS3盒子模型,box-sizing:content-box和box-sizing:border-box的讲解
前端·css·css3