实现功能:
- 点击上传按钮可上传图片,并且可定义最多可上传的图片数量、限制图片的大小、类型和来源。
- 点击图片可预览图片。
- 点击删除按钮可删除图片。
<!-- image-upload.wxml -->
<view class="container">
<view class="image-item" wx:if="{{files.length}}" wx:for="{{files}}" wx:key="*this">
<image class="image" src="{{item}}" mode="aspectFill" data-index="{{index}}" bindtap="handlePreviewImage"></image>
<view class="delete-icon" data-index="{{index}}" bindtap="handleDeleteImage">X</view>
</view>
<!-- 图片数量小于最多可上传的图片数量,则显示选择图片的按钮 -->
<view class="choose-image" wx:if="{{files.length < maxCount}}" bindtap="handleChooseImage">+</view>
</view>
// image-upload.js
Component({
properties: {
// 展示的图片列表
files: {
type: Array,
value: [],
},
// 最多可上传的图片数量
maxCount: {
type: Number,
value: 1,
},
// 单张图片的大小限制,单位 M
size: {
type: Number,
value: 1,
},
// 图片大小类型。original:原图,comperssed:压缩图
sizeType: {
type: Array,
value: ['original', 'comperssed'],
},
// 图片来源类型。album:从相册选图,camera:使用相机
sourceType: {
type: Array,
value: ['album', 'camera'],
}
},
methods: {
// 预览图片
handlePreviewImage: function(e) {
const {index} = e.currentTarget.dataset
const {files} = this.data
wx.previewImage({
urls: files,
current: files[index],
})
},
// 删除图片
handleDeleteImage: function(e) {
const {index} = e.currentTarget.dataset
let files = [...this.data.files]
files.splice(index, 1)
this.setData({files})
},
// 选择图片
handleChooseImage: async function() {
const {files, maxCount, sizeType, sourceType, size} = this.data
// 选择图片
const res = await wx.chooseMedia({
mediaType: 'image',
count: maxCount - files.length,
sourceType,
sizeType,
})
// 校验图片大小是否合法
const illegal = res.tempFiles.some(item => item.size > (size * 1024 * 1024))
if (illegal) {
return wx.showToast({
title: `图片大小不能超过${size}M`,
icon: 'none',
})
}
// 获取到图片的本地临时路径
const chooseImages = res.tempFiles.map(item => item.tempFilePath)
// 调用后端接口上传图片,获取图片的真实地址
chooseImages.forEach((item, index) => {
wx.uploadFile({
url: 'https://test/file/upload', // 上传文件的服务器接口地址
filePath: item,
name: index,
success: function(res) {
this.setData({
files: [...this.data.files, res.data.url]
})
},
fail: function(e) {
wx.showToast({
title: `第${index + 1}张图片上传失败`,
icon: 'none',
})
}
})
})
}
},
})
/* image-upload.wxss */
.container {
display: flex;
flex-wrap: wrap;
}
.image-item {
width: 200rpx;
height: 200rpx;
margin: 20rpx;
position: relative;
}
.image {
width: 100%;
height: 100%;
}
.delete-icon {
width: 50rpx;
height: 50rpx;
background: #888888;
color: #fff;
opacity: .8;
border-radius: 50%;
position: absolute;
z-index: 9999;
top: -18rpx;
right: -18rpx;
display: flex;
align-items: center;
justify-content: center;
}
.choose-image {
width: 200rpx;
height: 200rpx;
margin: 20rpx;
border: 2rpx dotted #888888;
font-size: 80rpx;
color: #888888;
display: flex;
align-items: center;
justify-content: center;
}