系列文章传送门:
目录
首先我们看一下要完成的效果:
这种场景还是非常常见的,点击分享的时候我们可以转发给好友,或者生成当前页的海报图片保存到手机相册中。分享给好友这个功能可以通过 button 的 open-type 方式实现,那自动保存图片到本地该如何实现呢,让我们来看一看吧:
一、封装分享组件
首先我们要封装一个分享的组件,这样方便在其他的页面中复用。这样就大大减少了代码的冗余,
在 components 文件夹中新建一个组件,下面是完整代码
share.wxml:
-
<!-- 底部自定义分享菜单栏 -->
-
<view class="share-sheet-mask flex-column" hidden="{{!showShareSheet}}" catchtap="closeShareSheet">
-
<view class="share-sheet">
-
<view class="items flex-row">
-
<view class="item flex-column">
-
<button class="ico flex-row" open-type="share">
-
<image class="img wx-ico" src="../../images/ico_wx.svg">
</image>
-
</button>
-
<view class="desc">微信好友
</view>
-
</view>
-
<view class="item flex-column">
-
<button class="ico flex-row" catchtap="genPlayBill">
-
<image class="img img-ico" src="../../images/ico_img.svg">
</image>
-
</button>
-
<view class="desc">生成海报
</view>
-
</view>
-
</view>
-
<view class="cancel-share-sheet">取消
</view>
-
</view>
-
</view>
share.js:
-
Component({
-
/**
-
* 组件的属性列表
-
*/
-
properties: {
-
-
},
-
/**
-
* 组件的初始数据
-
*/
-
data: {
-
showShareSheet:
false
-
},
-
/**
-
* 组件的方法列表
-
*/
-
methods: {
-
openShareSheet(
) {
-
this.
setData({
showShareSheet:
true})
-
},
-
closeShareSheet(
) {
-
this.
setData({
showShareSheet:
false});
-
},
-
genPlayBill(
) {
-
this.
triggerEvent(
'genPlayBill')
-
},
-
}
-
})
在点击生成海报的时候,我们向父组件发送了一个事件来调用 genPlayBill 方法,因为这个方法显然不应该在当前组件内定义,应该根据不同场景来定义我们只需要调用它就可以了。
share.wxss:
-
.flex-column {
-
display: flex;
-
flex-direction: column;
-
align-items: center;
-
justify-content: space-between;
-
}
-
-
.flex-row {
-
display: flex;
-
flex-direction: row;
-
align-items: center;
-
justify-content: space-between;
-
}
-
-
.share-sheet-mask {
-
position: fixed;
-
top:
0;
-
left:
0;
-
right:
0;
-
bottom:
0;
-
background:
rgba(
0,
0,
0,
0.60);
-
z-index:
101;
-
justify-content: flex-end;
-
}
-
-
.share-sheet-mask
.share-sheet {
-
padding:
0
24rpx;
-
background:
#f1f1f1;
-
border-radius:
16rpx
16rpx
0px
0px;
-
width:
100%;
-
box-sizing: border-box;
-
}
-
.share-sheet-mask
.share-sheet
.items {
-
padding:
48rpx
0
31rpx
0;
-
justify-content: space-around;
-
border-bottom:
0.5px solid
rgba(
39,
36,
71,
0.20);
-
}
-
.share-sheet-mask
.share-sheet
.items
.item{
-
text-align: center;
-
}
-
.share-sheet-mask
.share-sheet
.items
.item
.ico {
-
width:
80rpx;
-
height:
80rpx;
-
background:
#ffffff;
-
border-radius:
50%;
-
box-shadow:
0
0
12rpx
0
rgba(
204,
204,
204,
0.60);
-
padding:
0;
-
margin:
0;
-
padding:
0;
-
}
-
/*去除button的默认黑边框*/
-
.share-sheet-mask
.share-sheet
.items
.item
.ico
::after{
-
border: none;
-
}
-
.share-sheet-mask
.share-sheet
.items
.item
.ico
.img {
-
margin: auto;
-
}
-
.share-sheet-mask
.share-sheet
.items
.item
.ico
.wx-ico {
-
width:
52rpx;
-
height:
40rpx;
-
}
-
.share-sheet-mask
.share-sheet
.items
.item
.desc {
-
font-size:
24rpx;
-
font-family: PingFangSC, PingFangSC-Regular;
-
color:
#6d6d6d;
-
margin-top:
14rpx;
-
}
-
.share-sheet-mask
.share-sheet
.items
.item
.ico
.img-ico {
-
width:
44rpx;
-
height:
44rpx;
-
}
-
.share-sheet-mask
.share-sheet
.cancel-share-sheet {
-
margin:
31rpx auto
80rpx auto;
-
font-size:
32rpx;
-
font-family: PingFangSC, PingFangSC-Regular;
-
color:
#272447;
-
text-align: center;
-
}
二、定义用户授权方法
刚刚我们封装了顶部的分享组件,那现在就要去定义保存图片到相册的方法了,我们写代码的时候一定要考虑清楚这段代码是否是可复用的,是否应该剥离出去。显然保存图片到相册这个方法我们应该写在 utils 目录中,因为有很多其他的场景都可以用这个方法,那我们就封装一个公用方法,参数就是图片的地址,成功的回调函数和失败的回调函数。
最复杂的就是用户授权了,我们一起看一下代码结构:
-
const
saveImgToPhotos = (
imgPath, succCallback, failedCallback) => {
-
-
wx.
getSetting ({
// 查询所有授权
-
success(
res) {
-
if (res.
authSetting[
'scope.writePhotosAlbum']) {
// 用户已经授权
-
save()
// 执行保存函数
-
}
else {
// 未授权
-
wx.
authorize({
scope:
'scope.writePhotosAlbum',
-
success(
) {
// 用户同意授权
-
save()
// 执行保存函数
-
},
-
fail(
err) {
// 用户拒绝授权
-
if (err && err.
errMsg.
endsWith(
"auth deny")) {
-
wx.
showModal({
-
title:
'授权添加到相册',
-
content:
'需要获取您的添加相册权限,请确认授权,否则分享功能无法正常使用',
-
success:
function (
resolve) {
-
if (resolve.
confirm) {
// 用户同意设置授权
-
wx.
openSetting({
-
success(
res) {
-
if (res && res.
authSetting[
'scope.writePhotosAlbum']) {
-
save()
// 执行保存函数
-
}
-
},
-
fail(
res) {
// 用户拒绝设置授权
-
console.
log(res)
-
failedCallback(
'没有权限,保存失败')
-
}
-
})
-
}
else {
// 用户拒绝设置
-
failedCallback(
'没有权限,保存失败')
-
}
-
}
-
})
-
}
else {
-
failedCallback(err && err.
errMsg ||
'保存失败')
-
}
-
}
-
})
-
}
-
},
-
})
-
}
通过 wx.authorize() 来申请权限的方式是比较繁琐的。因为它的状态比较多,大致可分为:
- 用户未接受或拒绝过此权限,会弹窗询问用户,用户点击同意 —— 可调用相应接口。
- 用户未接受或拒绝过此权限,会弹窗询问用户,用户点击拒绝 —— 打开设置页面。
- 如果用户已授权 —— 可调用相应接口。
- 用户已拒绝授权 —— 打开设置页面。
上述情况的2/4是需要小伙伴们结合 wx.openSetting() 来帮助用户进行二次授权的。
搞定了用户授权这个麻烦事后,下面就是定义我们的 save 保存函数了,这个就很简单了:
-
let save =
function (
) {
-
wx.
saveImageToPhotosAlbum({
-
filePath: imgPath,
-
success(
) {
-
succCallback()
-
},
-
fail(
res){
-
failedCallback(res)
-
}
-
})
-
}
把这段代码添加到 saveImgToPhotos 方法中就ok了,调用 wx.saveImageToPhotosAlbum 方法,参数就是我们传进来的图片地址,成功的话就执行成功的回调,失败就执行失败的回调。
下面是官方的文档说明:
三、调用流程
下面我们就把组件,方法这些东西引入到我们的页面中。在页面的 json 文件中引入组件路径。
把组件引入页面wxml中:
<share-sheet id="share-sheet" catch:genPlayBill="genTimelineImage" />
这里的方法就是点击生成海报的时候调用的父组件的方法。
当点击分享的时候展示分享组件:
-
openShareSheet(
e) {
-
this.
selectComponent(
"#share-sheet").
openShareSheet()
-
},
在这里通过选择器可以直接调用子组件中的方法,来控制分享组件的显示与隐藏。
-
genTimelineImage(
e) {
-
wx.
showLoading({
-
title:
"海报生成中",
-
icon:
"loading",
-
mask:
true,
-
})
-
const imgSrc =
`路径`
-
wx.
getImageInfo({
-
src: imgSrc,
-
})
-
.
then(
(res) => {
-
wx.
hideLoading()
-
this.
imgTempPath = res.
path
-
this.
saveTimelineImg()
-
})
-
.
catch(
(err) =>
console.
log(err))
-
},
-
-
saveTimelineImg:
function (
) {
-
saveImgToPhotos(
this.
imgTempPath,
function(
){
-
this.
selectComponent(
"#share-sheet").
closeShareSheet()
-
}.
bind(
this),
function(
errMsg) {
-
this.
selectComponent(
"#share-sheet").
closeShareSheet()
-
}.
bind(
this))
-
},
当我们点击生成海报调用 genTimelineImage 方法的时候,通过 wx.getImageInfo 方法读取想要保存图片的临时下载路径,把他保存到外部定义的一个变量中,这样方便我们在 utils 目录中定义的 saveImgToPhotos 方法调用。这样我们整个的流程就over啦!
转载:https://blog.csdn.net/qq_49900295/article/details/128252612