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>
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论