关于uni-App webView 与 H5相互通信的问题

夜雨入心

APP部分

<template>
        <view class="box">
            <web-view :src="getRouter" ref="videoWebView" id="videoWebView"
            @message="handleMessage"></web-view>
        </view>
</template>
<script>
    import {mapGetters,mapMutations} from 'vuex'
    export default {
        data() {
            return {
                 wv: null
            };
        },
        computed:{
            ...mapGetters(['user','token','openid']),
            getRouter:function(){
                let url =''
                url = `http://192.168.3.131:8001/`
                return url
            }
        },
        methods:{
            ...mapMutations(['SET_INDEX']),
            handleMessage:function(e){//app接收到 h5内容传来的信息
                let data=e.detail.data[0]
            },
            h5Message:function(e){// H5接收到 H5内容传来的信息(uni中 h5中使用webview 嵌套h5时)
                let data=e.data.data
                if(data.name && data.name==="postMessage"){
                    data=data.arg
                }else{
                    return 
                }    
            },
            sendMessageH5:function(){
                let that=this
                let params=that.encodeParams({token:that.token,openid:that.openid})
                that.wv.evalJS(`savaParams("${params}")`)
                //此处 双引号为重点 ,被坑一小时!!!
            }
        },
        onShow:function(){
            let that=this
            if(that.wv){//页面切换时 重新发送消息
                that.sendMessageH5()
            }
            // #ifdef H5
            //扩展 当项目不为App为H5时 向h5通信
            if(document.getElementsByTagName("iframe")[0]){
                let params={token:that.token,openid:that.openid}
                document.getElementsByTagName("iframe")[0].contentWindow.postMessage(params, "*");
            }
            // #endif  
        },
        onReady:function(){
            let that = this;
            // #ifdef H5
            //H5接收消息方法
            window.addEventListener("message", this.h5Message, false)
            //扩展当 不为APP为H5时,向webview通信
            if(document.getElementsByTagName("iframe")[0]){
                let that=this
                let params={token:that.token,openid:that.openid}
                document.getElementsByTagName("iframe")[0].contentWindow.postMessage(params, "*");
            }
            // #endif  
            // #ifdef APP-PLUS
            // App初始化拿到webView 进行发送消息
            var currentWebview = that.$scope.$getAppWebview() 
            that.$nextTick(()=>{
                that.wv = currentWebview.children()[0]
                that.sendMessageH5()
            })
            // #endif      
        },
        onUnload:function(){
            // #ifdef H5
            window.removeEventListener("message", this.h5Message, false)
            // #endif
        }
    }
</script>

H5部分(uni 打包的H5)

main.js中

import Vue from 'vue'
import webUni from '@/static/js/webview.js'
//此处用的是uni 提供的 https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js
//有重大bug 需要修改js 
Vue.prototype.$webUni=webUni

H5部分 (webview.js中)

image.png
格式化后大约182行,
原代码 :var E = "undefined" != typeof uni ? uni: {};
修改为 :var E = "undefined" != typeof webUni ? webUni: {};
否则默认导出会找不到uni ,被框架覆盖!!!

对应页面中:

methods:{
    sendMessage:function(){
        this.$webUni.postMessage({
            data:{
                type:'swichTab',
                index:0,
                id:0,
                path:'/pages/tabbar/index'
            }
        })
    }
}

H5接收 app传递的消息

App.js中

methods: {
            ...mapMutations(['SET_TOKEN','SET_OPENID']),
            savaParams:function(params){
            //处理传递的信息
                let query=this.decodeParams(params)
                this.SET_TOKEN((query.token||''))
                this.SET_OPENID((query.openid||''))
            },
            getH5Message:function(e){//H5->H5
                let token='',openid=''
                if(e.data.token){
                    token=e.data.token
                    openid=e.data.openid
                }else if(e.currentTarget.location.search){//首次无法拿到,只有切换...等时,所以从url中获取
                    let result=e.currentTarget.location.search.split('?')[1]
                    result=result.split('&')
                    result.map(res=>{
                        let param=res.split('=')
                        if(param[0]==='token'){
                            token=param[1]
                        }else if(param[0]==='openid'){
                            openid=param[1]
                        }
                    })
                } 
            },
        },
onLaunch: function(options) {
            let that=this
            window.addEventListener("message", this.getH5Message, false)//H5->H5
            window.savaParams=that.savaParams//App->H5
            //window挂载的方法与 app evalJS()中方法名一致
        },
阅读 2.1k
34 声望
0 粉丝
0 条评论
34 声望
0 粉丝
文章目录
宣传栏