阿宁啊
阿宁啊
  • 发布:2021-02-27 22:16
  • 更新:2022-05-27 20:28
  • 阅读:7739

uni组件之——webview与APP之间的通讯

分类:uni-app

首先,让我们来谈谈应用的业务场景。大伙的业务场景是什么样我不知道,我来谈谈我踩坑时的业务场景。

老板:我们有个移动端的网页项目,但是为了唬客户,我们需要把这个网页打包成ios端和安卓端的app,页面中有一个需要调用摄像头的拍照签到功能。

我内心活动:ok,uni + webview没跑了,但是webview是不能直接调用手机的摄像头的,他的逻辑大概是,点击网页的签到按钮触发一个事件,事件给app发送一个我要使用手机摄像头的需求,然后再uni中收到了信号,去调起手机的摄像头。

所以,搞明白了业务场景,不管三七二十一,先上案例,看看最简单的demo咋实现。

html页面:

首先模拟一个网页,我们就用一个静态的html网页就好。webview要访问本地静态页面的话,静态页面是需要放在static目录底下的,在这我们命名为index.html

<!DOCTYPE html>  
<html lang="zh">  
<head>  
    <meta charset="UTF-8">  
    <meta name="viewport" content="width=device-width, initial-scale=1.0">  
    <meta http-equiv="X-UA-Compatible" content="ie=edge">  
    <title>网页实时向APP发送消息</title>  
    <!-- uni 的 SDK,必须引用。 -->    
    <script type="text/javascript" src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js"></script>  
    <!-- 微信 JS-SDK 如果不需要兼容小程序,则无需引用此 JS 文件。 -->    
    <script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>    
</head>  
<body>  
    <script type="text/javascript">  
        // 在引用依赖的文件后,需要在 HTML 中监听 UniAppJSBridgeReady 事件触发后,才能安全调用 uni 的 API。  
        document.addEventListener('UniAppJSBridgeReady', function() {  
            uni.getEnv(function(res) {    
                console.log('当前环境:' + JSON.stringify(res));    
            });  
            //向APP发送消息  
            uni.postMessage({  
                data: {  
                    action: 'message'  
                }  
            });  
            //接收APP发送过来的消息  
            handleMessage(evt) {    
                console.log('接收到的消息:' + JSON.stringify(evt.detail.data));    
            }    
        });  
    </script>  
</body>  
</html>

uni页面:

这里为index.nvue页面(注意这个nvue,跟vue页面是有差别的,后面就是踩坑点之一)

<template>  
    <view class="webview-box">  
        <web-view ref="webview" class="webview" src="../../static/index.html" @onPostMessage="handleMessage"></web-view>  
    </view>  
</template>  
<script>  
    export default {  
        data() {  
            return {  
                wv: null  
            }  
        },  
        onLoad() {  
            const self = this;  
            // #ifdef APP-PLUS    
            let currentWebview = getCurrentPages()[0];  
            setTimeout(function() {  
                self.wv = currentWebview.$getAppWebview();  
                 //调用下面函数  
                 self.handlePostMessage("消息");  
            }, 1000);  
            // #endif  
        },  
         mouted(){  
         },  
        methods: {  
            // 接收h5页面发来的键值判断需要执行的操作  
            handleMessage(evt) {  
                console.log("postMessage: ", evt)  
            },  
            // 获取到对应webview(关键)通过evalJs(注意大小写,如果不知道evalJ是什么,可自行百度) 执行网页的函数,可对其进行传参,完成与网页的通讯  
            handlePostMessage(res) {  
                this.$refs.webview.evalJs(`handleMessage(${res})`);  
            }  
        }  
    }  
</script>  

<style>  
    .webview-box {  
        position: absolute;  
        left: 0px;  
        right: 0px;  
        top: 0px;  
        bottom: 0px;  
    }  

    .webview {  
        flex: 1;  
    }  
</style>  

​ 好了,是不是觉得很简单,事实上也很简单,但是鄙人非出脑瘫,踩了两个巨坑。两个都是在uni的页面的,如果大伙也踩到的话,那恭喜了,看到了我。

​ 第一,我用的是nvue页面,nvue获取webview窗口的方式是与普通vue获取webview的方式不一样的,这一步非常关键,如果获取不正确就算你以下写的东西是正确的也没有效果,具体是什么原理我也没深究,以后懂了再更好了,先实现业务。具体获取方法看案例,自己console一下看看要获取的是哪个webview,因为如果大伙的项目是有自定义导航栏获取其他nuve组件的话也算是一个webview。

​ 第二个坑就是,一定要用在uni的webview组件上使用@onPostMessage这个方法进行消息的监听,我当时也不知道犯了什么病,我用的是message,老半天调不出。message只有在特定的情况下才会接收到网页的消息,比如你执行了返回或着其他的特定场景操作的时候,具体可以看官网给出的。踩坑记录就到这啦,希望能帮助到大伙。

5 关注 分享
1***@163.com 一抱一个胖猪猪 lindsy 勾栏听曲 x***@163.com

要回复文章请先登录注册

y***@foxmail.com

y***@foxmail.com

回复 小权 :
请问怎么实时获取呢,我的他是没有反应的 他必须要要在 UniAppJSBridgeReady 的时候只能调用一次,之后调用没有点击事件的情况就不好用了
2022-05-27 20:28
阿宁啊

阿宁啊 (作者)

回复 小权 :
谢谢!
2022-03-03 22:32
小权

小权

1.现在都是v3编译模式,vue中@message就可以实时接收web-view中网页uni.postMessage,不一定要用nvue。
2.web-view中网页可以调用plus。只是调用摄像头这些5+已实现的原生能力,直接调用plus,这么做大可不必。一般是在要网页中调用uniapp的原生插件才按你这种方式去实现
2022-02-18 10:19
lindsy

lindsy

我用 .vue 配合 @message 好像可以实时收到 html 的 postMessage?
2022-01-14 18:01
宝哥哥会飞

宝哥哥会飞

回复 佛系程序员 :
jssdk.miniProgram.postMessage 小程序用这个 集成下jssdk就好了
2021-12-28 11:18
宝哥哥会飞

宝哥哥会飞

回复 云淡风轻gfg :
jssdk.miniProgram.postMessage 小程序用这个
2021-12-28 11:14
佛系程序员

佛系程序员

回复 1***@topsida.com :
不能用
2021-10-21 22:53
佛系程序员

佛系程序员

这个在Android端可以用,微信小程序就没用,有知道为什么的兄弟吗?一直没找到原因
2021-10-21 22:53
1***@topsida.com

1***@topsida.com

回复 云淡风轻gfg :
小程序能用吗?
2021-10-21 15:17
云淡风轻gfg

云淡风轻gfg

微信小程序能用吗
2021-10-05 16:05