vue图片压缩与批量上传
使用el-upload组件
支持批量上传和图片压缩。
前端需要引入 image-conversion
- multiple设置为true,允许批量上传
- auto-upload设置为false,关闭自动上传
在on-change的时候校验文件名和文件大小
增加一个上传到服务器的按钮
<template>
<div class="">
<el-upload ref="pictureupload"
:multiple="true"
:action="uploadfileurl"
list-type="picture-card"
:disabled="check"
:on-change="handleonchange"
:before-upload="beforupload"
:on-success="handleuploadsuccess"
:auto-upload="false"
:file-list="showfile">
<i slot="default"
class="el-icon-plus"></i>
<div slot="file"
slot-scope="{file}">
<img class="el-upload-list__item-thumbnail"
:src="file.url"
alt="">
<span class="el-upload-list__item-actions">
<span class="el-upload-list__item-preview"
:disabled="true"
@click="handlepicturecardpreview(file)">
<i class="el-icon-zoom-in"></i>
</span>
<span v-if="!check"
class="el-upload-list__item-delete"
@click="handleremovethis(file)">
<i class="el-icon-delete"></i>
</span>
</span>
</div>
</el-upload>
<el-button style="margin-left: 10px;"
size="small"
v-if="!check"
type="success"
@click="submitupload">图片提交到服务器</el-button>
<el-dialog :visible.sync="dialogvisible"
title="预览"
width="800"
append-to-body>
<img :src="dialogimageurl"
style="display: block; max-width: 100%; margin: 0 auto;">
</el-dialog>
</div>
</template>
<script>
import { gettoken } from "@/utils/auth";
import * as imageconversion from 'image-conversion';
import { delimg } from "@/api/system/vote"
export default {
name: 'jimageupload',
props: ['imageurl', 'check'],
data () {
return {
allloading: [],
oldimg: null,
dialogimageurl: '',
checkupload: false,
filelist: [],
returnfilelist: [],
showfile: [],
urlstr: [],
editfile: [],
dialogvisible: false,
uploadfileurl: process.env.vue_app_base_api + "/sys/minio/upload", // 上传的图片服务器地址
headers: {
authorization: "bearer " + gettoken(),
},
};
},
mounted () { // 在mounted时候赋值,子组件只更新一次,后面重新选择后展示此组件的数据,不再更新
this.oldimg = this.imageurl
this.stringtoimage(this.oldimg)
},
watch: {
imageurl: function (val) {
// // console.log('val')
// // console.log(val)
this.oldimg = val
this.stringtoimage(this.oldimg)
}
},
created () {
},
methods: {
stringtoimage (imagestring) {
this.showfile = []
this.editfile = []
if (imagestring != null && imagestring != '' && imagestring != undefined) {
this.urlstr = imagestring.split(",");
this.urlstr.foreach(item => {
let obj = new object();
let obj1 = new object();
obj1.url = item;
if (item.indexof("http") < 0) {
item = process.env.vue_app_base_minio_api + item;
}
obj.url = item;
this.showfile.push(obj);
this.editfile.push(obj1);
});
}
},
arrytostring (arry) {
var imgstring = ""
if (arry.length > 0) {
for (var i = 0; i < arry.length; i++) {
if (i < arry.length - 1) {
imgstring += arry[i].url + ",";
} else {
imgstring += arry[i].url
}
}
}
return imgstring
},
// 点击查看图片
handlepicturecardpreview (file) {
this.dialogimageurl = file.url;
this.dialogvisible = true;
},
handleonchange (file, filelist) {
if (file.name.indexof(',') !== -1) {
this.msgerror("上传的文件名称中不允许出现英文逗号!");
this.handleremovethis(file)
return false
} else {
const islt2m = file.size / 1024 / 1024 < 1;
if (!islt2m) {
console.log(file)
// return new promise((resolve) => {
// 压缩到600kb,这里的600就是要压缩的大小,可自定义
imageconversion.compressaccurately(file.raw, 600).then(res => {
file.raw = new window.file([res], file.name, { type: file.type })
file.size = file.raw.size
this.filelist.push(file)
});
// })
} else {
this.filelist.push(file)
}
}
},
// 文件上传
submitupload () {
// 全屏禁用开启
this.allloading = this.$loading({
lock: true,
text: '图片上传中...',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
let filelist = []
let { uploadfiles, action, data } = this.$refs.pictureupload
// console.log(uploadfiles)
// uploadfiles.foreach(file => {
// imageconversion.compressaccurately(file.raw, 600).then(res => {
// file.raw = new window.file([res], file.name, { type: file.type })
// file.size = file.raw.size
// });
// })
// console.log(uploadfiles)
this.uploadfiles({
uploadfiles,
data,
action,
success: (response) => {
var res = json.parse(response)
// this.$refs.uploadfile.clearfiles();
// console.log(res)
this.msgsuccess("图片上传成功!")
this.allloading.close()
res.data.filename.foreach(item => {
let obj = new object();
let obj1 = new object();
obj.url = process.env.vue_app_base_minio_api + item;
obj1.url = item;
this.editfile.push(obj1)
this.showfile.push(obj)
var imgstring = this.arrytostring(this.editfile)
this.$emit('returnurl', imgstring)
})
},
error: (error) => {
this.msgerror("图片上传失败!")
this.allloading.close()
console.log('图片上传失败!', error)
}
})
},
/**
* 自定义上传文件
* @param filelist 文件列表
* @param data 上传时附带的额外参数
* @param url 上传的url地址
* @param success 成功回调
* @param error 失败回调
*/
uploadfiles ({ uploadfiles, headers, data, action, success, error }) {
let form = new formdata()
// 文件对象
uploadfiles.map(file => form.append("filedatas", file.raw))
// 附件参数
for (let key in data) {
form.append(key, data[key])
}
let xhr = new xmlhttprequest()
// 异步请求
xhr.open("post", action, true)
// 设置请求头
xhr.setrequestheader("authorization", gettoken());
xhr.onreadystatechange = function () {
if (xhr.readystate == 4) {
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
success && success(xhr.responsetext)
} else {
error && error(xhr.status)
}
}
}
xhr.send(form)
},
// 移除图片
handleremovethis (file) {
// console.log(file)
// 在控件中移除图片
this.$refs.pictureupload.handleremove(file)
// 获取图片在数组中的位置
var number = this.showfile.indexof(file)
// 获取返回的文件url中此文件的url
var file = process.env.vue_app_base_minio_api + this.editfile[number].url.tostring()
var fileitemlist = file.split('/')
// 执行文件删除
delimg(fileitemlist[4]).then(response => {
// // console.log(response)
})
this.editfile.splice(number, 1)
this.showfile.splice(number, 1)
var imgstring = this.arrytostring(this.editfile)
this.$emit('returnurl', imgstring)
},
// 上传前
beforupload (file) {
console.log("上传之前")
console.log(file)
if (file.name.indexof(',') !== -1) {
this.msgerror("上传的文件名称中不允许出现英文逗号!");
return false
} else {
// this.checkupload = true
this.filelist.push(file)
const islt2m = file.size / 1024 / 1024 < 1;
if (!islt2m) {
return new promise((resolve) => {
// 压缩到100kb,这里的100就是要压缩的大小,可自定义
imageconversion.compressaccurately(file.raw, 600).then(res => {
resolve(res);
});
})
}
}
},
// 上传成功
handleuploadsuccess (res, file, filelist) {
// this.checkupload = false
// console.log("上传成功")
// console.log(res)
// console.log(filelist)
console.log(this.$refs.pictureupload.uploadfiles)
this.$message.success("上传成功");
// filelist.foreach(item => {
// let obj = new object();
// let obj1 = new object();
// if (item.response !== undefined) {
// obj.url = process.env.vue_app_base_minio_api + item.response.filename;
// obj1.url = item.response.filename;
// this.editfile.push(obj1)
// this.showfile.push(obj)
// var imgstring = this.arrytostring(this.editfile)
// this.$emit('returnurl', imgstring)
// }
// })
let obj = new object();
let obj1 = new object();
obj.url = process.env.vue_app_base_minio_api + res.filename;
obj1.url = res.filename;
this.editfile.push(obj1)
this.showfile.push(obj)
var imgstring = this.arrytostring(this.editfile)
this.$emit('returnurl', imgstring)
},
handleuploaderror () {
this.$message({
type: "error",
message: "上传失败",
});
this.loading.close();
},
},
};
</script>
<style scoped lang="scss">
.image {
position: relative;
.mask {
opacity: 0;
position: absolute;
top: 0;
width: 100%;
background-color: rgba(0, 0, 0, 0.5);
transition: all 0.3s;
}
&:hover .mask {
opacity: 1;
}
}
</style>总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论