1.上传图片组件
<template>
<view class="basicUploadImage flex flex-wrap">
<slot name="before"></slot>
<!-- 已经上传过的图片 -->
<view
class="imageWrap"
:style="imageStyle"
v-for="(item, index) in imageList"
:key="index"
>
<image
class="image"
:src="item.url"
@click="$common.previewImage([item])"
></image>
<image
@click.stop="delImage(index, 'cur')"
class="delIcon"
:src="imgPrefixUrl && imgPrefixUrl + 'pic_del@2x.png'"
></image>
</view>
<!-- 当前正在上传的图片 -->
<view class="imageWrap" :style="imageStyle" v-if="curImageUrl">
<image
class="image"
:src="item"
@click="$common.previewImage([{ url: item }])"
></image>
<view class="progressLine">
<view
v-if="imageProgressPercent && imageProgressPercent !== 1"
class="line"
:style="'width:' + progressWidth + 'rpx'"
></view>
</view>
</view>
<!-- 等待上传的图片列表 -->
<block v-if="waitImageList.length">
<view
class="imageWrap"
:style="imageStyle"
v-for="(item, index) in waitImageList"
:key="index"
>
<image
class="image"
:src="item"
@click="$common.previewImage([{ url: item }])"
></image>
<image
@click.stop="delImage(index, 'wait')"
class="delIcon"
:src="imgPrefixUrl && imgPrefixUrl + 'pic_del@2x.png'"
></image>
<view class="progressLine">
<view class="line" style="width: 2rpx"></view>
</view>
</view>
</block>
<view
v-if="imageList.length + waitImageList.length < maxNum"
class="uploadImage imageWrap"
:style="imageStyle"
@click="onUploadClick"
>
<image
:src="imgPrefixUrl && imgPrefixUrl + 'upload_pic%402x.png'"
></image>
<view class="add">上传图片</view>
</view>
<slot name="after"></slot>
</view>
</template>
<script>
import { mapGetters, mapState } from "vuex";
export default {
props: {
//图片样式
imageStyle: {
default: "",
type: String,
},
//最大上传数量
maxNum: {
default: 9,
type: Number || String,
},
//图片列表
imageList: {
default: function () {
return [];
},
type: Array,
},
//是否
},
data() {
return {
curImageUrl: "", //正在上传的图片
waitImageList: [], //等待上传的图片列表
};
},
computed: {
// imageProgressPercent 全局上传图片的进度
...mapState(["imgPrefixUrl", "imageProgressPercent"]),
/**
* @author: yaoxueke
* @description: 设置视频进度条
* @param {*}
* @return {*}
*/
progressWidth() {
let totalWidth = 192; //进度条完成时宽度
let lineWidth = (totalWidth * (this.imageProgressPercent / 100)).toFixed(
2
);
return lineWidth;
},
},
methods: {
/**
* @author: yaoxueke
* @description: 删除图片
* @param {*} index 索引
* @param {*} type cur 删除当前的视频 wait删除等待的视频
* @return {*}
*/
delImage(index, type) {
if (type === "wait") {
this.waitImageList.splice(index, 1);
} else {
this.$emit("delImage", index);
}
},
/**
* @author: yaoxueke
* @description: 上传视频
* @param {*}
* @return {*}
*/
uploadImage() {
this.$common.uploadImageFun(0, [this.curImageUrl], (imgInfo) => {
this.curImageUrl = "";
this.$emit("updateImage", imgInfo);
if (this.waitImageList.length) {
this.curImageUrl = this.waitImageList[0];
this.waitImageList.splice(0, 1);
this.uploadImage();
}
});
},
/**
* @author: yaoxueke
* @description: 上传图片
* @param {*}
* @return {*}
*/
onUploadClick() {
let num = this.curImageUrl
? this.maxNum - this.imageList.length - this.waitImageList.length - 1
: this.maxNum - this.imageList.length - this.waitImageList.length;
this.$common.chooseImage(num).then((res) => {
let data = res;
if (!this.curImageUrl) {
//等待列表没有图片,说明是第一次选择图片,从选择的第一张开始上传
this.curImageUrl = data[0];
data.splice(0, 1); //删除第一张,如果还有,其他加入等待上传的图片列表
if (data.length) {
data.forEach((item) => {
this.waitImageList.push(item);
});
}
this.uploadImage();
} else {
//等待列表有图片,就把所有的图片添加到等待列表
res.forEach((item) => {
this.waitImageList.push(item);
});
}
});
},
},
};
</script>
<style lang="scss" scoped>
.basicUploadImage {
.imageWrap {
position: relative;
margin: 14rpx 12rpx 0 0;
.image {
width: 100%;
height: 100%;
border-radius: 14rpx;
border: 2rpx dashed rgba(0, 0, 0, 0.15);
}
.progressLine {
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 12rpx;
border-radius: 8rpx;
border: 1px solid #0feada;
.line {
border-radius: 10rpx;
background: #0feada;
width: 0;
height: 100%;
}
}
.delIcon {
width: 30rpx;
height: 30rpx;
position: absolute;
right: -10rpx;
top: -10rpx;
z-index: 9;
}
}
.uploadImage {
// text-align:center;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
// margin:0 auto;
border-radius: 20rpx;
border: 2rpx dashed rgba(0, 0, 0, 0.15);
background: rgba(0, 0, 0, 0.02);
margin-top: 16rpx;
image {
width: 72rpx;
height: 72rpx;
}
.add {
font-size: 24rpx;
color: #4e4e4e;
margin-top: 18rpx;
}
}
}
</style>
2.全局设置一个进度字段(在此设置在vuex中)
state:{
imageProgressPercent:0,
},
mutations:{
setImageProgressPercent(state,data){
state.imageProgressPercent = data
}
},
3.上传请求中监听上传进度变化并更新全局进度值
Vue.prototype.$store.commit('setImageProgressPercent',0) //每次上传前进度置0
return new Promise((resolve,reject) => {
let uploadTask = uni.uploadFile({
url,
name: "file",
header,
formData:args.formData || {},
filePath: args.path,
// #ifdef MP-ALIPAY
fileType:args.fileType || '',
// #endif
success:function(res){
if(res.statusCode === 200 && JSON.parse(res.data).code === '000000'){
Vue.prototype.$store.commit('setImageProgressPercent',100) //上传成功后进度设置100
resolve(JSON.parse(res.data).resData)
}else{
console.error(res,'上传图片返回错误信息')
uni.showToast({
title: res && res.msg,
icon: 'none',
mask: true
})
reject(res)
}
},
fail:function(err){
console.error(err,'上传图片返回错误信息')
uni.showToast({
title: err && err.msg,
icon: 'none',
mask: true
})
reject(err)
}
});
//监听上传进度
uploadTask.onProgressUpdate((res) => {
let progress = Number(res.progress) > 92 ? 92 : Number(res.progress)
Vue.prototype.$store.commit('setImageProgressPercent',progress)
if(res.progress == 100){
uploadTask.offProgressUpdate(() => {
console.log('取消监听')
})
uploadTask = ''
}
});
})
4.在页面
<basicUploadImage
ref="basicUploadImage"
:maxNum="9"
imageStyle="width:184rpx;height:184rpx;"
:imageList="picUrl"
@updateImage="updateImageHandle"
@delImage="delImageHandle"
>
</basicUploadImage>
picUrl:[{url:‘’}]
updateImageHandle(imgInfo){
console.log(imgInfo,'上传图片服务器返回数据')
}
//删除图片 index 索引
delImageHandle(index){
picUrl.splice(0,index)
}
中使用