描述
批量上传图片, 可设置最大上传个数, 可删除, 可设置默认值。
效果
源码
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"
}
}