• vue分片上传


    uploader.vue:

    <template>
      <div id="page">
    
        <div class="main">
          <uploader ref="uploader" :options="options" :file-status-text="fileStatusText" :autoStart="false" @file-added="onFileAdded" @file-progress="onFileProgress" @file-success="onFileSuccess" @file-error="onFileError" class="uploader">
            <uploader-unsupport></uploader-unsupport>
            <uploader-drop>
              <uploader-btn class="upfile"><i class="iconfont icon-upload"></i> 上传文件</uploader-btn>
            </uploader-drop>
            <uploader-list></uploader-list>
          </uploader>
        </div>
    
      </div>
    </template>
    
    <script>
    import axios from 'axios';
    import SparkMD5 from 'spark-md5'
    import { Merge } from "@/api/api.js"
    export default {
      data() {
        return {
          fileMD5: '',
          identifier: '',
          options: {
            target: this.$TF.baseURL + 'api/file/UploadChunk',//
            testChunks: false,
            chunkSize: 2097152,  //2MB
            simultaneousUploads: 1, //并发上传数
            headers: {},
            query: {
              identifier: ''
            },
            maxChunkRetries: 1, //最大自动失败重试上传次数
            parseTimeRemaining: function (timeRemaining, parsedTimeRemaining) { //格式化时间
              return parsedTimeRemaining
                .replace(/\syears?/, '年')
                .replace(/\days?/, '天')
                .replace(/\shours?/, '小时')
                .replace(/\sminutes?/, '分钟')
                .replace(/\sseconds?/, '秒')
            }
          },
          statusTextMap: {
            success: '上传成功',
            error: '上传出错了',
            uploading: '上传中...',
            paused: '暂停',
            waiting: '等待中...',
            cmd5: '计算md5...'
          },
          fileStatusText: (status, response) => {
            return this.statusTextMap[status];
          },
        }
      },
      created() {
        this.options.headers.User = this.$TF.upHeaders()
        //const uploaderInstance = this.$refs.uploader.uploader;
      },
      mounted() {
        this.$nextTick(() => {
          let u = document.querySelector('.uploader-btn')
          let ipt = u.querySelector('input')
          ipt.setAttribute('accept', '.xls,.xlsx')
        })
      },
      methods: {
        onFileAdded(file) {
          file.pause();
          let fileSize = 1 * 1024 * 1024 * 1024
          // 计算MD5  
          
          if (fileSize < file.size) {
            this.$message({ message: '文件不能大于1G', type: 'error' })
            return
          }
    
          this.computeMD5(file);
        },
        chkMd5(file) {
          let time = new Date().getTime();
          let fileReader = new FileReader();
          let spark = new SparkMD5(); //创建md5对象(基于SparkMD5)
          fileReader.readAsBinaryString(file.file);
          //文件读取完毕之后的处理
          fileReader.onload = (e) => {
            spark.appendBinary(e.target.result);
            let md5 = spark.end();
            // console.log(`MD5计算完成:${file.name} \nMD5:${md5} \n用时:${new Date().getTime() - time} ms`);
            spark.destroy();
          };
        },
        //计算MD5
        computeMD5(file) {
          let blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice,
            chunkSize = 2097152,
            chunks = Math.ceil(file.size / chunkSize),
            currentChunk = 0,
            spark = new SparkMD5.ArrayBuffer(),
            fileReader = new FileReader();
          let time = new Date().getTime();
          // console.log('计算MD5...')
          file.cmd5 = true;
    
          fileReader.onload = (e) => {
            spark.append(e.target.result);   // Append array buffer
            currentChunk++;
    
            if (currentChunk < chunks) {
              // let md5 = spark.end();
              // this.options.query.md5 = md5
              // console.log(`第${currentChunk}分片解析完成,md5:${md5}, 开始第${currentChunk + 1} / ${chunks}分片解析`)
    
              // spark.destroy(); //释放缓存
              // file.uniqueIdentifier = md5; //将文件md5赋值给文件唯一标识
              //      console.log(file,md5);
              // file.cmd5 = false; //取消计算md5状态
              //  file.resume(); //开始上传
              // let percent = Math.floor(currentChunk / chunks * 100);
              // console.log(percent);
              // file.cmd5progress = percent;
              loadNext();
            } else {
              // console.log('finished loading');
              let md5 = spark.end();
              this.fileMD5 = md5
              this.identifier = this.$TF.guid()
              this.options.query.identifier = this.identifier
              spark.destroy(); //释放缓存
              // file.uniqueIdentifier = md5; //将文件md5赋值给文件唯一标识
              file.cmd5 = false; //取消计算md5状态
              file.resume(); //开始上传
              // console.log(file);
            }
          };
          fileReader.onerror = () => {
            file.cancel();
          };
    
          let loadNext = () => {
            let start = currentChunk * chunkSize,
              end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize;
    
            fileReader.readAsArrayBuffer(blobSlice.call(file.file, start, end));
          };
    
          loadNext();
        },
        // 文件进度的回调
        onFileProgress(rootFile, file, chunk) {
          // console.log(`上传中 ${file.name},chunk:${chunk.startByte / 1024 / 1024} ~ ${chunk.endByte / 1024 / 1024}`)
        },
        onFileSuccess(rootFile, file, response, chunk) {
          let resp = JSON.parse(response);
          if (resp.state == 0) {
            let obj = {
              fileName: file.name,
              identifier: this.identifier,
              totalSize: file.size,
              totalChunks: chunk.offset + 1,
              md5: this.fileMD5
            }
            Merge(obj).then((res) => {
              if (res.data.state == 0) {
                this.$emit('func', res.data)
              } else {
    
              }
            });
          } else {
    
          }
        },
        onFileError(rootFile, file, response, chunk) {
        },
      },
    
    }
    </script>
    
    <style scoped lang="scss">
    .main {
      max- 1000px;
    
      background: #fff;
      padding: 10px;
      h2 {
        padding: 30px 0;
        text-align: center;
        font-size: 20px;
      }
    }
    .uploader {
       100%;
      padding: 15px;
      font-size: 14px;
      box-shadow: 0 0 10px rgba(0, 0, 0, 0.4);
      box-sizing: border-box;
      .uploader-btn {
        margin-right: 4px;
        color: #fff;
        padding: 6px 16px;
      }
      .upfile {
        border: 1px solid #409eff;
        background: #409eff;
      }
      .updir {
        border: 1px solid #67c23a;
        background: #67c23a;
      }
      .uploader-list {
        max-height: 440px;
        overflow: auto;
        overflow-x: hidden;
        overflow-y: auto;
    
        height: 356px;
        /deep/.iconfont {
          font-size: 18px;
          color: #409eff;
        }
        .no-file {
          text-align: center;
          font-size: 14px;
          padding-top: 50px;
          color: #ccc;
        }
      }
    }
    //手机等小屏幕手持设备。当设备宽度  在  320px和768px之间时,执行当前的css
    @media only screen and (min- 320px) and (max- 768px) {
      .uploader {
         98%;
        padding: 0;
        box-shadow: none;
      }
    }
    </style>
    
  • 相关阅读:
    go 自定义RWMutex
    go defer的*i和i参数
    go defer 易错题
    EasyPlayer移动端播放webrtc协议时长按播放页面无法关闭“关于我们”页面
    高速公路服务区智能一体机解决方案
    【操作教程】TSINGSEE青犀视频平台如何将旧数据库导入到新数据库?
    EasyPlayer流媒体播放器播放HLS视频,起播速度慢的技术优化
    开发那些事儿:如何在CentOS7下安装部署ffmpeg?
    开发那些事儿:前端开发环境报错“[vuex]unknown action type”如何解决?
    H.264转码H.265出现崩溃并报错“missing picture”该如何解决?
  • 原文地址:https://www.cnblogs.com/Fancy1486450630/p/15703274.html
Copyright © 2020-2023  润新知