常见小程序分享分为:
- 分享给朋友
- 分享到朋友圈
- 短链接分享
- 生成二维码分享
准备
页面1:pages/from/from 用来触发分享
页面2:pages/to/to 模拟打开分享后得页面
分享给朋友
右上角分享
页面中定义 onShareAppMessage 方法。不定义此方法,右上角分享给朋友置灰不可用。
onShareAppMessage 方法 return 一个对象,用于自定义转发内容:
onShareAppMessage() {
const promise = new Promise(resolve => {
setTimeout(() => {
resolve({
title: 'promise定义的转发标题'
})
}, 5000) // 超出3秒,使用默认定义
});
return {
title: '转发标题',
path: '/pages/to/to', // 转发后打开的路径,默认为当前页面,必须以/开头的完整路径
imageUrl: 'http://img.netbian.com/file/2024/0819/232435idR4n.jpg', // 分享图片,默认使用截图
promise //如果该参数存在,则以 resolve 结果为准,如果三秒内不 resolve,分享会使用上面传入的默认参数
}
}
传递参数:
onShareAppMessage() {
return {
title: '转发标题',
path: '/pages/to/to?name=Tony&age=18', // 直接在路径上添加参数
}
}
接收参数:
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
console.log('to页面接受参数',options)
},
自定义按钮
<button open-type="share">分享</button>
当然真实开发中我们很少能接受这么丑的按钮。我们可以使用 position:absolute 将按钮放到 UI 设计的按钮上,并且通过opacity: 0 设置透明不可见。
其余部分和右上角分享一样,在此不做赘述。
分享到朋友圈
右上角分享
在页面开启了 onShareAppMessage 的前提下,再在页面中定义 onShareTimeline 方法。不定义此方法,右上角分享到朋友圈置灰不可用。
onShareTimeline 方法 return 一个对象,用于自定义转发内容(不支持自定义页面路径):
// 分享朋友圈
onShareTimeline(){
return {
title:"朋友圈列表页面上显示的标题",
imageUrl: 'http://img.netbian.com/file/2024/0819/232435idR4n.jpg', // 分享图片,默认使用小程序logo
}
}
传递参数:通过query传递参数
// 分享朋友圈
onShareTimeline(){
return {
title:"朋友圈列表页面上显示的标题",
imageUrl: 'http://img.netbian.com/file/2024/0819/232435idR4n.jpg', // 分享图片,默认使用小程序logo
query:'name=tony&age=19'
}
}
接收参数:
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
console.log('from页面接收参数',options);
},
自定义按钮--暂不支持
目前只支持右上角分享到朋友圈,不支持自定义按钮分享到朋友圈。
单页面模式
点击分享到朋友圈的链接打开小程序时,进入的是小程序单页模式。
在单页面模式中,页面底部有固定的操作栏进入小程序。进入正式小程序后,朋友圈传递的参数依旧在 option 中,不会丢失。
可以通过wx.getLaunchOptionsSync().scene获取场景值为1154,判断打开方式是朋友圈内打开“单页模式” ,由此来进行页面适配等操作(由于页面固定有顶部导航栏与底部操作栏,很可能会影响小程序页面的布局)。
点击进入小程序后场景值变为1155,表示:“单页模式”打开小程序。
单页面可实现的交互与接口能力有限,存在限制如下:
- 页面无登录态,与登录相关的接口,如
wx.login均不可用;云开发资源需开启未登录访问方可在单页模式下使用,详见未登录模式。 - 不允许跳转到其它页面,包括任何跳小程序页面、跳其它小程序、跳微信原生页面
- 不允许横屏使用
- 若页面包含
tabBar,tabBar不会渲染,包括自定义tabBar - 本地存储与小程序普通模式不共用
短链接分享
右上角复制链接
右上角复制链接是微信的默认行为,目前没有找到可以自定义打开页面的方法。
传递参数:
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
this.shortLinkAddQuery();
},
/**
* 绑定分享参数
*/
shortLinkAddQuery() {
let query = `queryA=1&queryB=2`;
//监听用户点击右上角菜单的「复制链接」按钮时触发的事件。本接口为 Beta 版本,暂只在 Android 平台支持。
wx.onCopyUrl(() => {
return {
query
}
})
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
// 取消绑定分享参数,防止影响其它页面。
wx.offCopyUrl()
},
接收参数:
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
console.log('from页面接收参数',options);
},
自定义按钮
注意:pageUrl必须是已经发布的小程序存在的页面,否则生成链接会失败。
生成短链接的接口需要后端调用,所以需要后端提供接口/api/get/link。
<button bindtap="getShareLink">复制链接</button>
/**
* 点击获取短链
*/
getShareLink() {
const params = {
pageUrl: `pages/find/find?a=Tony&b=18`, //通过 Short Link 进入的小程序页面路径,必须是已经发布的小程序存在的页面,可携带 query,最大1024个字符
pageTitle: '自定义标题',
};
//隐藏弹出框
wx.showLoading({
title: '链接生成中',
mask: 'true'
})
wx.request(`/api/get/link`, "POST", params).then(res => {
wx.hideLoading();
if (res.status == '200') {
if (res.data) {
wx.setClipboardData({
data: res.data,
success: function (res) {
}
})
} else {
wx.showToast({
icon: 'error',
title: '请稍后再试',
})
}
} else {
wx.showToast({
icon: 'error',
title: '请稍后再试',
})
}
})
},
接收参数依旧在options中。
二维码分享
通过后台接口可以获取小程序任意页面的小程序码,扫描该小程序码可以直接进入小程序对应的页面
获取二维码
获取小程序二维码需要后端调用微信官方接口,所以需要后端支持。传参方式也就自然和后端协商了。
需要注意,只能生成已经发布的小程序的二维码。
// getQrCode函数在后续
<button bindtap="getQrCode">生成二维码</button>
<image class="qrCode" wx:if="{{qrCode}}" src="{{qrCode}}" mode=""/>
普通展示二维码
// 生成海报
getQrCode() {
let params = {
page: `pages/to/to`,
params: `queryA=a&queryB=b`
}
wx.showLoading({
title: '图片生成中',
mask: true
});
wx.request('/getCodeRul', 'post', params).then(res => {
if (res.status == '2000') {
const qrCodeImg = `data:image/png;base64,${res.data}`
console.log('地址', qrCodeImg)
this.setData({
qrCode: qrCodeImg
});
wx.hideLoading();
}
})
},
二维码长按操作
so easy,添加show-menu-by-longpres属性即可弹出
<image show-menu-by-longpress="{{true}}" class="qrCode" wx:if="{{qrCode}}" src="{{qrCode}}" mode=""/>
按钮下载二维码
<button bindtap="downLoadQrcode">下载二维码</button>
downLoadQrcode(){
const {qrCode} = this.data;
var steam = wx.getFileSystemManager();
steam.writeFile({
filePath: wx.env.USER_DATA_PATH + '/poster.png',
data: qrCode.slice(22),
encoding: 'base64',
success: res => {
wx.saveImageToPhotosAlbum({
filePath: wx.env.USER_DATA_PATH + '/poster.png',
success: function () {
wx.hideLoading()
wx.showModal({
title: '保存图片成功',
content: '图片已经保存到您的相册',
showCancel: false,
success: function (res) {},
fail: function (res) {},
complete: function (res) {},
});
},
fail: function (res) {
wx.hideLoading()
if (res.errMsg == "saveImageToPhotosAlbum:fail cancel") {
wx.showModal({
title: '保存图片失败',
content: '您已取消保存图片到相册!',
showCancel: false
});
} else {
wx.showModal({
title: '提示',
content: '保存图片失败,您可以点击确定设置获取相册权限后再尝试保存!',
complete: function (res) {
if (res.confirm) {
wx.openSetting({}) //打开小程序设置页面,可以设置权限
} else {
wx.showModal({
title: '保存图片失败',
content: '您已取消保存图片到相册!',
showCancel: false
});
}
}
});
}
}
})
},
fail: err => {
console.log(err)
}
})
},
获取参数
由于二维码的参数长度存在限制,若是参数比较长,可以存在后端,扫码时从后端获取:
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
let scene = decodeURIComponent(options.scene); //"id=1234"
}
海报展示二维码
-
首先准备
wxml-to-canvas,详细介绍戳这里。<wxml-to-canvas class="widget" ></wxml-to-canvas>并且让元素在页面内不可见:
.widget{ width: 0; height: 0; overflow: hidden; display: block; position: fixed; left: 0; top: 10000%; z-index: -1111; } -
获取
wxml-to-canvas实例/** * 生命周期函数--监听页面加载 */ onLoad(options) { this.widget = this.selectComponent('.widget') }, -
获取二维码并绘制海报
const {wxmls,styles} = require('./utils'); Page({ // 生成海报 getQrCode() { let params = { page: `pages/to/to`, params: `queryA=a&queryB=b` } wx.showLoading({ title: '图片生成中', mask: true }); let that = this; app.request('/api/getQrcode', 'post', params).then(res => { if (res.status == '2000') { const qrCodeImg = `data:image/png;base64,${res.data}` this.setData({ qrCode: qrCodeImg }); const backSrc = 'http://img.netbian.com/file/2024/0819/232435idR4n.jpg'; const p1 = that.widget.renderToCanvas({ wxml: wxmls(qrCodeImg, backSrc), style: styles }) p1.then((res) => { wx.hideLoading(); const p2 = that.widget.canvasToTempFilePath() p2.then(res => { console.log('回执图片地址', res); that.setData({ src: res.tempFilePath }, function () { wx.hideLoading(); }) }).catch(fail => { wx.hideLoading(); console.log(fail) wx.showToast({ icon: 'error', title: '请稍后再试', }) }) }).catch(fail => { wx.hideLoading(); wx.showToast({ icon: 'error', title: '请稍后再试', }) }) } }) }, }) -
wxml模板和样式const wxmls = (erweima, backImg) => { return ` <view class="popbox"> <image class="backlogo" src="` + backImg + `"/> <image class="qrcode" src="` + erweima + `"/> </view> ` }; const width = 300, height = 455; const styles = { backlogo: { position: "relative", width, height, }, qrcode:{ position:'absolute', width:160, height:160, borderRadius:80, bottom:20, right:20 } } module.exports = { styles, wxmls }
保存海报
/**
* 点击保存二维码
*/
saveImg() {
const that = this;
const p2 = this.widget.canvasToTempFilePath();
p2.then(res => {
wx.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success(res) {
wx.showModal({
content: '海报已保存到相册',
showCancel: false,
confirmText: '确定',
confirmColor: '#333',
success: function (res) {
if (res.confirm) {
//执行成功回调
}
},
fail: function (res) {}
})
}
})
})
},
海报总结
-
海报通过
wxmls设置模板,通过styles定义样式,并且每个元素必须设置weight和height不然不会显示。同时样式只支持部分属性,具体看这里 -
widget.renderToCanvas({wxml, style}): Promise:渲染到 canvas,传入 wxml 模板 和 style 对象,返回的容器对象包含布局和样式信息。 -
canvasToTempFilePath({fileType, quality}): Promise:提取画布中容器所在区域内容生成相同大小的图片,返回临时文件地址。
fileType支持jpg、png两种格式,quality 为图片的质量,目前仅对 jpg 有效。取值范围为 (0, 1],不在范围内时当作 1.0 处理