由于我们的小程序是使用 webview 组件来实现展示功能,最近有个需求需要做微信小程序分享功能,用户通过分享的卡片来跳转到具体的 webview 地址页面。
经过查阅官方文档,发现 webview 无法直接调用微信的分享功能。
如果是小程序内,可以通过按钮触发分,只需要给
button
组件设置属性open-type="share"
,就可以在用户点击按钮后触发onShareAppMessage
事件。
那么问题来了,现在只能通过小程序右上角的更多来实现分享了。所以需要解决一个问题
小程序如何获取 webview 的 url 以及对应需要分享的内容,例如 title
,path
,imageUrl
?
postMessage
小程序的 webview 的 jssdk 提供了 wx.miniProgram.postMessage
,只需要引入 jssdk.js 即可以在 h5 内部跟小程序通信。思路来了,那就搞起来吧。
小程序端
在 webview 绑定 message
事件
<web-view src="{{url}}" bindmessage="onPostMessage"></web-view>
Page({
onPostMessage(e) {
let obj = e.detail.data[e.detail.data.length - 1]; // data 是多次 postMessage 的参数组成的数组,所以我们获取最后一次
this.setData({
message: obj,
});
},
onShareAppMessage: function () {
let that = this;
return {
title: that.data.message.title,
path: "/pages/home?url=" + encodeURIComponent(that.data.message.url),
imageUrl: that.data.message.imageUrl,
};
},
});
H5 项目
通过 postMessage
发送消息
wx.miniProgram.postMessage({
data: {
url: "https://www.1024nav.com",
title: "前端面经"
}
});
这样就可以实现在 webview 内部的小程序分享功能。
FAQ
- 无法在
bindmessage
里面实时获取postMessage
的数据?
网页向小程序 postMessage 时,会在特定时机(小程序后退、组件销毁、分享)触发并收到消息。e.detail = { data },data 是多次 postMessage 的参数组成的数组
所以 bindmessage
事件是在真正到了点击分享的时候才会触发,这个 postMessage
方法应该在 h5 页面初始化的时候就开始调用。下面以 vue 为例
{
mounted() {
window.wx.miniProgram.postMessage({
data: { url: "https://www.1024nav.com", title: "前端面经" },
});
},
}
- 路径参数丢失
由于小程序会截取 #
后面的参数,尽量别用 hash 路由,使用 history 路由即可。