[组件封装]微信小程序-图片批量上传照片墙

时间:2023-03-10 03:16:00
[组件封装]微信小程序-图片批量上传照片墙

描述

批量上传图片, 可设置最大上传个数, 可删除, 可设置默认值。

效果

[组件封装]微信小程序-图片批量上传照片墙
[组件封装]微信小程序-图片批量上传照片墙

源码

pictures-wall.wxml

<view class="picturesWall">
<view class="picBox" wx:for="{{mydata}}" wx:key="{{index}}">
<image class="pic" src="{{item.filePath || item.url}}" /> <view class="picDelete" data-index="{{index}}" bindtap="handleImageDelete">x</view>
</view>
<view class="picBox" wx:if="{{canUseCount > 0}}" bindtap="handleUpload">
<view class="addicon"></view>
</view>
</view>

pictures-wall.js

Component({
properties: {
mydata: Array,
mymaxcount: Number,
}, data: {
value: [], // 暂存上传结果
canUseCount: 0, // 可使用个数
}, observers: {
'mydata, mymaxcount': function (mydata, mymaxcount) {
this.setData({ canUseCount: (mymaxcount || 3) - mydata.length });
},
}, methods: {
handleUpload: function () {
const { canUseCount } = this.data;
wx.chooseImage({
count: canUseCount,
success: (res) => {
wx.showLoading();
Promise.all(res.tempFilePaths.map(d => this.uploadFile(d)))
.finally(() => { // app.js中实现promise finally
wx.hideLoading();
this.triggerEvent('mychange', [...this.data.mydata, ...this.data.value]);
this.data.value = []; // 清空上传结果
})
}
})
}, uploadFile: function (filePath) {
return new Promise((resolve, reject) => {
wx.uploadFile({
url: '--url--',
filePath,
name: 'file',
success: (res) => {
if (res.statusCode === 200) {
let json = JSON.parse(res.data);
this.data.value.push({
filePath,
// 业务数据
});
resolve();
return;
}
reject();
},
fail: (err) => {
reject(err);
}
})
}) }, handleImageDelete: function ({ currentTarget: { dataset: { index } } }) {
const { mydata } = this.data;
mydata.splice(index, 1);
this.triggerEvent('mychange', mydata);
}, } })

pictures-wall.wxss

.picBox {
position: relative;
display: inline-block;
vertical-align: top;
width: 208rpx;
height: 208rpx;
margin-right: 26rpx;
margin-bottom: 26rpx;
border-radius: 4rpx;
border: 1px solid rgba(204,204,204,1);
} .pic {
width: 100%;
height: 100%;
} .picDelete {
position: absolute;
left: -32rpx;
top: -32rpx;
height: 64rpx;
width: 64rpx;
line-height: 64rpx;
text-align: center;
} .picturesWall .picBox:nth-child(3n) {
margin-right: 0;
} .addicon {
position: absolute;
display: inline-block;
left: 104rpx;
top: 54rpx;
height: 100rpx;
width: 0rpx;
border-right: 1px solid #CCCCCC;
}
.addicon::after {
content: '';
position: absolute;
top: 50rpx;
left: -50rpx;
display: block;
height: 0rpx;
width: 100rpx;
border-bottom: 1px solid #CCCCCC;
}

pictures-wall.json

{
"component": true,
"usingComponents": {}
}

app.js

由于微信小程序Promise finally, 所以要在app.js里实现一下。

App({
onLaunch: function () {
// finally
Promise.prototype.finally = function (callback) {
let P = this.constructor;
return this.then(
value => P.resolve(callback()).then(() => value),
reason => P.resolve(callback()).then(() => { throw reason })
);
};
}, globalData: { }
})

使用例子

test.wxml

<pictures-wall mydata="{{picList}}" mymaxcount="{{9}}" bindmychange="handlePicturesChange" />
<pictures-wall mydata="{{picList1}}" mymaxcount="{{9}}" bindmychange="handlePicturesChange1" />

test.js

Page({
data: {
picList: [],
picList1: [{url: 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1567767650570&di=e99314caaadc830e9b590311945cdbaa&imgtype=0&src=http%3A%2F%2Fimages.liqucn.com%2Fh027%2Fh13%2Fimages201508311321540_info200X200.png'}],
}, handlePicturesChange: function ({ detail }) {
this.setData({ picList: detail })
},
handlePicturesChange1: function ({ detail }) {
this.setData({ picList1: detail })
},})

test.json

{
"navigationBarTitleText": "demo",
"usingComponents": {
"pictures-wall": "/components/pictures-wall/pictures-wall"
}
}