0


基于element UI 实现大文件分片上传

将文件进行切片,上传至服务器,上传完成后通知服务器进行合并

屏幕录制2022-11-11 16.40.06

  • 测试用例
<template><divname="test-upload-img"><s-upload-imgv-model="logo"></s-upload-img></div></template><script>exportdefault{name:"test-upload-img",extends:{},mixins:[],components:{},emits:[],props:{},data(){return{logo:"zfs/2022-11-11/0ae8e4f733fe4bbdbb00f92fb1247273.jpeg"}},created(){},methods:{}}</script>
  • s-upload
<script>import{getMinioUrl}from"../../../static/global.util";exportdefault{name:"s-upload",extends:{mixins:[]},components:{},emits:[],model:{},props:{value:{type:[String, Array]},// v-model 绑定的Objectlimit:{type: Number,default:1},// 控制 上传图片数量accept:{type: String,default:undefined},// 限制上传的文件类型},data(){return{fileList:[],chunkSize:1024*1024*6,// 6M 为一个切片,超过6M,则采用上传大文件的方法进行文件上传percentage:{},// 进度条}},computed:{action:{get(){returnthis.$getRequestUrl(this.$servers.openServer,'tb/minio/uploadImgCompress')}},previewImgs:{get(){returnthis.fileList.map(o=>getMinioUrl(o.url));},},hide:{get(){returnthis.fileList.length ===this.limit;}}},watch:{},created(){this.fileList =(this.value
            ?this.limit ===1?[{url:this.value}]:(this.value instanceofArray?this.value :JSON.parse(this.value)).map(o=>({url: o})):[]).filter(o=> o.url).map(({url})=>({url,name: url.slice(url.lastIndexOf('/')+1)})).map(o=>({...o,uid: o.name}));},methods:{
    getMinioUrl,onSuccess(res, file, fileList){this.fileList = fileList;let imgs =this.limit ===1? res.data.visitPath
          :JSON.stringify(fileList.map(img=> img.response ? img.response.data.visitPath : img.url))
      console.log(imgs)this.$emit('input', imgs);},handleRemove(file){this.fileList.splice(this.fileList.indexOf(file),1)let imgs =this.limit ===1?this.fileList.length <=0?'':this.fileList.length ===1&&this.fileList[0].response
                  ?this.fileList[0].response.data.visitPath
                  :this.fileList[0].url
          :JSON.stringify(this.fileList.map(img=> img.response ? img.response.data.visitPath : img.url))this.$emit('input', imgs);},httpRequest(params){let{file:{size}}= params;
      size >this.chunkSize ?this.uploadBigFile(params,this.chunkSize):this.uploadFile(params)},uploadFile(params){let{file, filename, onSuccess}= params;const formData =newFormData();
      formData.append(filename, file);const config ={'Content-type':'multipart/form-data',onUploadProgress:progress=>this.percentage = Math.floor(progress.loaded / progress.total *100)}this.$post(this.$servers.openServer,'tb/minio/upload', formData, config).then(onSuccess)},calculationPercentage(file, index, loadeds, size){const loaded = loadeds.filter(o=> o.length >0).map(o=> o[o.length -1]).reduce((prev, curr)=> prev + curr)this.$set(this.percentage, file.uid, Math.floor(loaded / size *100))},uploadBigFile(params, chunkSize){let{file, filename, onSuccess}= params;let{size, type, name}= file;const chunkLength = Math.ceil(file.size / chunkSize)let chunks = Array.from({length: chunkLength}).map((v, i)=> file.slice(i * chunkSize, i * chunkSize + chunkSize))let loadeds =[];let chunkRequests = chunks.map((chunk, i)=>{const formData =newFormData();
        formData.append(filename, chunk);
        loadeds[i]=[];const config ={'Content-type':'multipart/form-data',onUploadProgress:progress=>{
            loadeds[i].push(progress.loaded)this.calculationPercentage(file, i, loadeds, size);}}returnthis.$post(this.$servers.openServer,'tb/minio/upload', formData, config);})this.$axios.all(chunkRequests).then(res=>{let fileNames = res.map(({data:{minioPath}})=> minioPath)const params ={fileName: name,contentType: type,fileSize: size, fileNames}this.$post(this.$servers.openServer,'tb/minio/merge', params).then(onSuccess)})},onRemove(file, fileList){this.percentage =-1;}}}</script>
  • s-upload-img
<stylescopedlang="less">.hide-upload{/deep/ .el-upload{visibility: hidden;}}</style><template><divname="s-upload-img"><el-upload:class="{'hide-upload':hide}"list-type="picture-card"v-bind="$attrs":file-list="fileList":action="action":limit="limit":accept="accept":on-success="onSuccess":http-request="httpRequest"><islot="default"class="el-icon-plus"></i><divslot="file"slot-scope="{file}"><el-progressv-if="percentage[file.uid] && percentage[file.uid]<100"type="circle":percentage="percentage[file.uid]"></el-progress><img:src="getMinioUrl(file.url)"style="width:100%;height:auto;"alt=""><spanclass="el-upload-list__item-actions"><spanclass="el-upload-list__item-preview"@click="()=>this.$refs.previewImg.showViewer = true"><iclass="el-icon-zoom-in"></i></span><spanclass="el-upload-list__item-delete"@click="handleRemove(file)"><iclass="el-icon-delete"></i></span></span></div></el-upload><el-imageref="previewImg"v-show="false"src:preview-src-list='previewImgs'></el-image></div></template><script>import SUpload from"./s-upload";exportdefault{name:"s-upload-img",extends: SUpload,props:{accept:{type: String,default:'.jpeg,.jpg,.png'},// 限制上传的图片类型},}</script>

本文转载自: https://blog.csdn.net/qq_33547169/article/details/127807333
版权归原作者 菜鸟阿达 所有, 如有侵权,请联系我们删除。

“基于element UI 实现大文件分片上传”的评论:

还没有评论