
支持批量上传和图片压缩。
前端需要引入 image-conversion
在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="https://www.jb51.net/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="https://www.jb51.net/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>
以上为个人经验,希望能给大家一个参考,也希望大家多多支持本站。