uniapp 利用renderjs 解决【APP端】和【H5端】通讯问题

  问题背景:

 当 【H5】 嵌入到 【APP端】 后,想进行通讯,比如H5调用 APP端的扫描功能。该如何实现?

之前想过用 webView 但是 webView 会铺满窗口 这个有点不满足需求。

所以采用 iframe+ renderjs 的方式解决。

附上 renderjs 官方说明

https://uniapp.dcloud.net.cn/tutorial/renderjs.html#renderjs

下面以 H5端 点击按钮 调用APP端的扫描,然后将扫描结果返回H5端为案例

【APP端】代码

<template>
<view>
    
      <iframe style="width:100%;height:100%" id="iframe1" ref="iframe1" :src="url"                      width="100%" frameborder="0"></iframe>
    <!-- 主要是为了触发 renderjs -->
		<view
		      id="renderjs-view"
		      style="display: none;"
		      :msg="msg"
		      :change:msg="renderModal.receiveMsg"
		    />
</view>
  
</template>
<script>
    export default{
        data(){
			return{
                msg:"",//当这个值发生改变时 就会触发renderModal.receiveMsg 方法
				url:"http://xxxxx", //改成你自己要嵌入的地址
			}
		},
        methods:{
            //向 H5 发送消息
			sendMessage(data){
				data._Key=getGuid();//主要是为了触发 renderModal.receiveMsg 方法
				this.msg=JSON.stringify(data);
			},
            //================ APP API方法,由H5端调用============
			openScan(){
				// 调起条码扫描
				console.log("[APP端]调用扫描");
				uni.scanCode({
					success:  (res)=> {
						this.sendMessage({
                            msg:res.result
                        });
					}
				});
			}
          
        }
    }

</script>

<script module="renderModal" lang="renderjs">
    export default {
		data() {
			return {
				dom: '',
			}
		},
		mounted() {
			this.dom = document.getElementById('iframe1')
			console.log("[APP端]开启监听");
			window.addEventListener('message', this.postMessage);
		},
		methods: {
			receiveMsg(data){
				const newData= JSON.parse(data);
				delete newData._Key;//将这个参数删掉,不发送到H5端
				this.sendMessage(newData);
			},
			//APP端接收到的消息
			postMessage(e){
				console.log("[APP端]接收到的消息==>",e.data);
				//var params=JSON.parse(e.data);
				//调用打开扫描的方法
				this.$ownerInstance.callMethod("openScan");
			},
			//发送消息
			sendMessage(data){
				console.log("[APP端]发送消息",JSON.stringify(data));
                // * 号可以改成你自己的 域名,不改也行
				this.dom.contentWindow.postMessage(JSON.stringify(data),'*')
			},
		}
	}
</script>	

 补一个 getGuid() 方法,主要保证每次调用 sendMessage 都能触发 receiveMsg

/**
 * 获取32位guid
 * @param {*} fg 分隔符,默认不分割
 * @returns
 */
export function getGuid(fg = "") {
	let guid = getId(fg);

	//后面的数据位,完全采用随机数产生

	for (var i = 12; i <= 32; i++) {
		var g = Math.floor(Math.random() * 16).toString(16);

		guid += g;

		if (i == 12 || i == 16 || i == 20) {
			guid += fg;
		}
	}

	return guid.toUpperCase();
}
function getId(fg) {
	var guid = "";

	var prefix11 = ""; //基于时间产生的随机数

	var d = new Date();

	var x = Math.random(); //获取一个0~1之间的随机数

	var y = d.getTime(); //返回 1970 年 1 月 1 日至今的毫秒数

	if (x < 0.1) x += 0.1;

	//根据当前日期,产生GUID的前11位,避免GUID重复,引入一个随机数

	prefix11 = Math.round(x * y * 10).toString(16);

	guid += prefix11.substring(0, 8);

	guid += fg;

	guid += prefix11.substring(8, 11);
	return guid;
}

【H5端】代码

<template>
    <view>
        扫描结果:
          <input v-model="msg"/>
           <button @click="openScan">打开扫描</button>
    </view>
  
</template>

<script>
    export default{
        data(){
            return{
                msg:""
            }
        },
        onLoad(){
             //H5端 开启监听
             window.addEventListener("message", this.postMessage);
        },
        methods:{
            //H5端 接收消息
             postMessage(e){
                console.log("[H5端]H5接收的数据===>", e.data);
                const data= JSON.parse(e.data);
                this.msg=data.result;
             },
            //H5端 向APP发送消息
            sendMessage(data){
                //这个方法可以自行改造,可通过参数来决定调用 APP端的哪个方法
                window.parent.postMessage("你的参数,只能是字符串类型", "*");
            },
            openScan(){
                this.sendMessage({});
            }
        }

    }


</script>

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值