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: 第二个问题解决方案不是太优雅,如果有兄弟有更好的方案可以分享一下。

相关推荐
Hooray2 小时前
2026年,站在职业生涯十字路口的我该何去何从?
前端·后端
小二·2 小时前
Python Web 开发进阶实战:安全加固实战 —— 基于 OWASP Top 10 的全栈防御体系
前端·python·安全
over6972 小时前
🌟 JavaScript 数组终极指南:从零基础到工程级实战
前端·javascript·前端框架
社恐的下水道蟑螂2 小时前
深入掌握 AI 全栈项目中的路由功能:从基础到进阶的全面解析
前端·react.js·全栈
米诺zuo2 小时前
Angular 18 核心特性速查表
前端
hey_ner2 小时前
进度条图表简单化
前端·css·css3
苏西的网络日志2 小时前
前端项目缓存控制与自动版本检查方案实现
前端
小遁哥2 小时前
通过AI从零开发RN到在安卓手机上运行
前端·react native·cursor
sure2822 小时前
react native中实现视频转歌
前端·react native