uniapp小程序使用web-view承载的html页面是uniapp H5时,H5与小程序通讯

最近在小程序项目用到web-view,需要web-view承载的H5和小程序通讯,碰到个大坑,所以写一下实现过程及怎么避坑。

一、小程序向web-view承载的H5传递参数,直接在url后接参数即可(xxxxx.com

二、H5向小程序发送消息
  1. 在uniapp项目根目录创建 模板html

2、然后在模板html里引入微信SDK和uni SDK;注意,坑来了,uniapp官方提供的SDK链接 是错的(坑了我半天)用这个:https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js ,模板html代码如下


<!DOCTYPE html>
<html lang="zh-CN">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>
            <%= htmlWebpackPlugin.options.title %>
        </title>
        <!-- Open Graph data -->
        <!-- <meta property="og:title" content="Title Here" /> -->
        <!-- <meta property="og:url" content="http://www.example.com/" /> -->
        <!-- <meta property="og:image" content="http://example.com/image.jpg" /> -->
        <!-- <meta property="og:description" content="Description Here" /> -->
        <script>
            var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') || CSS.supports('top: constant(a)'))
            document.write('<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' + (coverSupport ? ', viewport-fit=cover' : '') + '" />')
        </script>
        <link rel="stylesheet" href="<%= BASE_URL %>static/index.<%= VUE_APP_INDEX_CSS_HASH %>.css" />
    </head>
    <body>
        <noscript>
            <strong>Please enable JavaScript to continue.</strong>
        </noscript>
        <div id="app"></div>
        <!-- built files will be auto injected -->
    </body>
    
    <!-- 可更换,两个SDK都可使用最近更新的版本 -->
    <!-- 微信 JS-SDK 如果不需要兼容小程序,可以不引用 JS 文件。 两个文件同时引入时,微信的需要在前-->
    <script type="text/javascript" src="//res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>  
    <!-- uni 的 SDK,必须引用。 -->  
    <script type="text/javascript" src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js"></script>
    
    <script>
        //执行UniAppJSBridgeReady,通过后才可调用uni的api
        document.addEventListener('UniAppJSBridgeReady', function() {
            console.log(uni)
            console.log('uni.webView', uni.webView)
            uni.webView.getEnv(function(res) {
                console.log('当前环境:' + JSON.stringify(res));
            });
        });
    </script>
</html>

3、在manifest.json中引入你创建好的模板html

4、然后就可以在你的页面使用


<template>
    <view class="layout">
        <view class="content">
            <view class="footer-box">
                <view class="confirm" @click="confirm">确认</view>
            </view>
        </view>
    </view>
</template>
<!-- <script src="./index.js"></script> -->

<script>
    export default {
        data() {
            return {
                
            }
        },
        onLoad() {
            
        },

        methods: {
            confirm() {
                //调用 uni.webView.postMessage 方法,向uniapp发送消息 postMessage ,
                //uniapp会在特定时机(后退、组件销毁、分享)触发并收到消息

                //先调用 uni.webView.navigateBack ,接着再调用 uni.webView.postMessage 
                //就会触发并接收到消息(调用顺讯不要反了,不然会触发不了发送消息)
                uni.webView.navigateBack()
                uni.webView.postMessage({
                    data: {
                        action: 'message' //发送的消息
                    }
                })
            },
        }
    }
</script>

5、最后,在web-view里接收消息即可


<template>
    <view>
        <web-view :webview-styles="webviewStyles" :src="webViewUrl" @message="getMssage"></web-view>
    </view>
</template>

<script>
    export default {
        data() {
            return {
                webviewStyles: {
                    progress: {
                        color: ' rgba(0, 126, 255, 0.99)'
                    }
                },
                webViewUrl: null
            }
        },
        
        onLoad() {
            //小程序仅支持加载网络网页,不支持本地html
            //因为是小程序所以需要进行 decodeURIComponent
            this.webViewUrl = decodeURIComponent('https://baidu.com?params=aaa')
        },

        methods: {
            // 在uniap中以 @message 触发并收到消息
            getMssage(e) {
                //接收到的消息 e.detail.data 数据格式为数组
                console.log('收到网页发来的消息', e.detail.data[0].action)
            },
        },
    }
</script>