Demo:uni-app template GitHub Address
problem
In demand, multiple images need to be uploaded, but wechat applet can only upload single image, and multi image upload only supports app and H5.
If you can only upload pictures one by one, the user experience is quite poor. I believe that the users who upload will be crazy
thinking
The official document also gives a solution, which is to call the API repeatedlyuni.uploadFile
resolvent
I used the plug-in of the uni app plug-in market (encapsulating the request network request library like Axios, supporting interceptors and task operations), and uni.uploadFile There are also packages.
Here, I am api.js The method of uploading pictures is also defined in the file of.
//Upload the picture. The interface name is defined according to its own back-end. This interface cannot be called
export const uploadToOss = (params) => axios.upload('/api/upload/xxx', {
...params,
custom: {
loading: true,
Loadingtitle: 'uploading...'
}
})
UploadPic.vue
<template>
<view class="upload_box">
<view class="image_list">
<view class="image_item" v-for="(item, index) in files" :key="index">
<view class="icon iconfont iconshanchu" @click="removeItem(index)"></view>
<image :src="item"></image>
</view>
<view class="upload" v-if="files.length < limit" @click="handleUpload">
<view class="icon iconfont iconshangchuan"></view>
<text>{{ btnText }}</text>
</view>
</view>
<view class="upload_tip" v-if="tip">{{ tip }}</view>
</view>
</template>
<script>
import { uploadToOss } from '@/api/http';
export default {
props: {
//Tips
tip: {
type: String,
default: ''
},
//Button text
btnText: {
type: String,
default: ''
},
//Limit the number of sheets at most, 1 by default
limit: {
type: Number,
default: 1
},
//Image type, used to distinguish multiple image upload components on the same page
imgType: {
type: String,
default: 'image'
}
},
data() {
return {
Files: [] // image address collection after uploading pictures
};
},
methods: {
/**
*@ description delete picture
*@ param {number} index index value of the image
*/
removeItem(index) {
this.files.splice(index, 1);
this.sendMessage (); // send message parent component
},
/**
*@ description upload image
*@ param {string} URL image temporary address
*/
uploadImg(url) {
return new Promise((resolve, reject) => {
uploadToOss({
filePath: url,
fileType: 'image',
name: 'file',
}).then(res => {
if(res._OK) {
resolve(res.data.data);
} else {
uni.showModal({
Title: 'prompt',
content: res.data.message ||'upload failed'
})
return new Promise.reject(res);
}
}).catch(err => {
return new Promise.reject(err);
})
})
},
/**
*@ description traverses and calls the upload interface
* @param {Array} tempFilePaths uni.chooseImage Temporary image address collection returned after picture selection
*@ returns {array} array the collection of addresses returned on the image server by asynchronously calling the upload interface
*/
async uploads(tempFilePaths) {
let arr = [];
for(let i = 0; i < tempFilePaths.length; i++) {
arr[i] = await this.uploadImg(tempFilePaths[i]);
}
return arr;
},
/**
*@ description upload image
*/
handleUpload() {
let _this = this;
uni.chooseImage({
count: _this.limit,
async success(chooseImageRes) {
//After selecting the image, call the image upload interface immediately. The await of ES6 must be included by async.
let files = await _this.uploads(chooseImageRes.tempFilePaths);
_this.files = [..._this.files, ...files];
_this.sendMessage (); // send message parent component
}
});
},
/**
*@ description sends information to parent component
*/
sendMessage() {
this.$emit('on-change', {
files: this.files,
imgType: this.imgType
});
}
}
};
</script>
<style lang="scss" scoped>
.upload_box {
.upload {
width: 120rpx;
height: 120rpx;
border: 2rpx solid #d9d9d9;
font-size: 24rpx;
color: #999999;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
margin-bottom: 20rpx;
.iconfont {
margin-bottom: 8rpx;
}
}
.image_list {
display: flex;
flex-wrap: wrap;
.image_item {
position: relative;
width: 120rpx;
height: 120rpx;
margin: 0 20rpx 20rpx 0;
z-index: 1;
image {
width: 120rpx;
height: 120rpx;
}
.iconfont {
color: #ff0000;
font-size: 30rpx;
position: absolute;
z-index: 10;
right: 0;
top: 0;
}
}
}
}
.upload_tip {
color: #999999;
font-size: 24rpx;
margin-top: -10rpx;
}
</style>
summary
The interaction and expansibility of the multi graph upload component is not good enough, but it basically meets the needs of the current product. After that, it will continue to be updated iteratively. I hope you can give more comments