pb 两个程序之间传递数据方案_微信小程序与内嵌H5页面交互实践

  • Post author:
  • Post category:小程序


af31b44a8a05c291303c1cab66341be7.gif
11c6d8907521034341dbf25142f133c0.gif
利用H5的hash特性来做数据交换

前言

目前小程序页面回退H5是无法带入数据的,例如用户A在H5上选择拍照,跳转到小程序页面拍照压缩并将照片地址带回H5展示出来。小程序与H5之间的交互目前只有官方给出的postMessage接口,并且只能在满足特定时机下触发message事件才能拿到数据。为满足日益繁杂的产品需求,提高迭代速度,又不能放弃小程序的优势功能,因此需要打通小程序与H5的数据交换。

实现方案

利用H5的hash特性,使H5知道有数据变化,并且页面不会刷新,如下图所示流程:

f684d7a2013a6115de4a44164083510e.png

关于windows.history.go(-1)

hash变更会导致页面历史栈长度+1,执行window.history.go(-1)保证和之前的url一致,并且history.go(-1)只后退不刷新,而history.back()后退+刷新。

踩坑

① webview的src是固定的,不会随着H5地址的变化而改变,因此H5跳转小程序需要将当前页面的url传递过去,设置H5的数据时回传过去,然后在onShow中重新组合url;

② 改变的hash值必须要和之前的不同,确保webview的src更新,触发H5的hashchange。

af31b44a8a05c291303c1cab66341be7.gif
11c6d8907521034341dbf25142f133c0.gif
使用示例

小程序跳转H5


1wx.navigateTo({

2url: 'webview路径' + `?src=${

encodeURIComponent(h5地址)}`3})

H5跳转小程序


1window.wx.miniProgram.navigateTo({

2//backUrl参数跳转的小程序页面会记住,以供后续回传使用3url: '小程序页面地址...' + `&backUrl=${

encodeURIComponent(H5当前页面的地址location.href)}`4})

af31b44a8a05c291303c1cab66341be7.gif
11c6d8907521034341dbf25142f133c0.gif
小程序代码示例


1Page({


2data: {


3src: '',

4canHtml: wx.canIUse && wx.canIUse('web-view')

5},

6onLoad(options) {


7let src = decodeURIComponent(options.src || '').replace(/(^\s*)|(\s*$)/g, '');

8//记录h5初始的URL

9this.baseUrl = src;

10this.setData({


11src: src || ''

12})

13},

14/**15* 设置H5的数据16* @param {Object} res - { data: 'xxx', backUrl: 'xxx' }17*/

18setH5Data(res) {


19//这里处理上面提到踩坑的第二点,v: Date.now()时间戳确保拼接webview的src与上一次的不同,触发H5的hashchange

20this.miniappData = encodeURIComponent(JSON.stringify({

data: res.data, v: Date.now()}));

21this.backUrl = res.backUrl ? decodeURIComponent(res.backUrl) : this.baseUrl;

22},

23onShow() {


24//h5站使用的是vue路由hash模式,这里直接拼接数据

25if (this.miniappData) {


26let src = this.backUrl + (this.backUrl.indexOf('?') > -1 ? '&' : '?') + `_miniappData=${

this.miniappData}`;

27this.miniappData = null;

28this.setData({


29src

30})

31}

32}

33})

af31b44a8a05c291303c1cab66341be7.gif
11c6d8907521034341dbf25142f133c0.gif
小程序

传值给H5


注意:


小程序返回H5先调用setH5Data方法传递数据再返回,参数格式 { data: ‘xxx’, backUrl: ‘xxx’


1goH5Page(data) {


2let pages = getCurrentPages();

3let pre = pages[pages.length - 2];

4pre.setH5Data && pre.setH5Data({


5data: data,

6backUrl: this.backUrl

7});

8wx.navigateBack();

9}

af31b44a8a05c291303c1cab66341be7.gif
11c6d8907521034341dbf25142f133c0.gif


监听示例:vue路由hash模式


1watch: {


2"$route.query._miniappData": {


3handler(val) {


4//vue有子路由,this.routePath记录了当前页的地址,如果当前是子路由,则只触发子路由的监听

5if (val && this.$route.path == this.routePath) {


6window.history.go(-1); //这个是核心

7let res = JSON.parse(decodeURIComponent(val)).data || "";

8xxx 业务逻辑

9}

10},

11deep: true

12}

13}

Tips

  • 上述示例是基础实现,有其他业务需求可扩展

  • 该功能已上线,体验很棒

交互展示

在下面的录屏展示中,除了《拍照识别身份证》页面为小程序的,其余的所有页面都是h5页面。

5654276b43375c6f19b4d20baecbc9b5.gif

acc29c293f2d425a31a72edbff7dedd2.gif



版权声明:本文为weixin_39686353原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。