ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

vue vue-simple-uploader 前端的简单使用

2021-12-21 19:03:43  阅读:171  来源: 互联网

标签:vue const uploader simple params file md5 上传 chunkSize


前言

因为项目需要上传大文件tif图,考虑使用分片上传。

1、安装

npm install vue-simple-uploader --save

2、main.js中初始化

import uploader from 'vue-simple-uploader'
Vue.use(uploader)

注:直接在vue文件中引用,居然加载不出来,不清楚原因

3、定义在template中的模板

点击查看代码
    <uploader
      ref="uploaderRef"
      :autoStart="false"
      :options="options"
      class="uploader-example"
      @file-success="onFileSuccess"
      @file-added="filesAdded"
      @file-error="onFileError"
      :file-status-text="fileStatusText"
    >
      <uploader-unsupport></uploader-unsupport>
      <uploader-drop>
        <p>将文件拖放到此处以上传或</p>
        <!-- <uploader-btn>select files</uploader-btn> -->
        <uploader-btn :attrs="attrs" :single="true">选择遥感图片</uploader-btn>
        <!-- <uploader-btn :directory="true">select folder</uploader-btn> -->
      </uploader-drop>
      <uploader-list></uploader-list>
    </uploader>

4、定义在script中的数据

点击查看代码
import SparkMD5 from 'spark-md5'
export default {
  props: {
    name: {
      type: String,
      default: 'file'
    },
    chunkSize: {
      type: Number,
      default: 0
    },
    action: {
      type: String,
      default: 'http://xxx.xxx.xx'
    }
  },
  data () {
    return {
      options: {
        target: this.action, // 目标上传 URL
        chunkSize: this.chunkSize, // 分块大小
        fileParameterName: this.name, // 上传文件时文件的参数名,默认file
        //  maxChunkRetries: 3, // 最大自动失败重试上传次数
        testChunks: false, // 是否开启服务器分片校验
        // // 服务器分片校验函数,秒传及断点续传基础
        checkChunkUploadedByResponse: function (chunk, message) {
          const objMessage = JSON.parse(message)
          if (objMessage.skipUpload) {
            return true
          }

          return (objMessage.uploaded || []).indexOf(chunk.offset + 1) >= 0
        },

        processParams (params) {
          console.log(params)

          // 每一次分片传给后台的参数,params是该方法返回的形参,包含分片信息
          return {
            // 返回一个对象,会添加到每一个分片的请求参数里面
            filename: params.filename,
            identifier: params.identifier,
            totalChunks: params.totalChunks,
            chunkNumber: params.chunkNumber,
            totalSize: params.totalSize
          }
        },
        headers: {
          // 在header中添加的验证,请根据实际业务来
          token: this.$store.getters['user/token']
        }
        // 自定义参数,随每一个切片发送
        //         query:{
        //            //列如,参数id
        //             id:''
        //         },
      },
      statusTextMap: {
        success: '上传成功',
        error: '上传失败',
        uploading: '上传中',
        paused: '暂停中',
        waiting: '等待中'
      },
      attrs: {
        // 接受的文件类型,形如['.png', '.jpg', '.jpeg', '.gif', '.bmp'...]
        accept: ['.tif', '.tiff']
      },
      // 将不同的状态对应文字
      fileStatusText: (status, response) => {
        return this.statusTextMap[status]
      }
    }
  },
  methods: {
    onFileSuccess (rootFile, file, response, chunk) {
      console.log(response)
      const res = JSON.parse(response)

      // 切片上传成功,调用合并
      if (res.code === 200) {
        this.$emit('needMerger', file.uniqueIdentifier)
      }
    },
    onFileError (rootFile, file, response, chunk) {
      // 文件上传失败的回调
      console.log(rootFile, file, response, chunk)
      this.$emit('onFileError')
    },
    computeMD5 (file) {
      const loading = this.$loading({
        lock: true,
        text: '正在计算文件大小',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      })
      const fileReader = new FileReader()
      const time = new Date().getTime()
      const blobSlice =
        File.prototype.slice ||
        File.prototype.mozSlice ||
        File.prototype.webkitSlice
      let currentChunk = 0
      const chunkSize = 10 * 1024 * 1000
      const chunks = Math.ceil(file.size / chunkSize)
      const spark = new SparkMD5.ArrayBuffer()
      file.pause()

      loadNext()

      fileReader.onload = e => {
        spark.append(e.target.result)
        if (currentChunk < chunks) {
          currentChunk++
          loadNext()
          this.$nextTick(() => {
            console.log(
              '校验MD5 ' + ((currentChunk / chunks) * 100).toFixed(0) + '%'
            )
          })
        } else {
          const md5 = spark.end()
          loading.close()
          this.computeMD5Success(md5, file)
          console.log(
            `MD5计算完毕:${file.name} \nMD5:${md5} \n分片:${chunks} 大小:${
              file.size
            } 用时:${new Date().getTime() - time} ms`
          )
        }
      }
      fileReader.onerror = function () {
        this.error(`文件${file.name}读取出错,请检查该文件`)
        loading.close()
        file.cancel()
      }

      function loadNext () {
        const start = currentChunk * chunkSize
        const end =
          start + chunkSize >= file.size ? file.size : start + chunkSize
        fileReader.readAsArrayBuffer(blobSlice.call(file.file, start, end))
      }
    },
    computeMD5Success (md5, file) {
      file.uniqueIdentifier = md5 // 把md5值作为文件的识别码
    },
    filesAdded (file, event) {
      if (this.$refs.uploaderRef.files.length === 1) {
        // 只上传一张,将上一张覆盖
        this.$refs.uploaderRef.files[0].cancel()
      }
      if (file.size / 1024 / 1024 / 1024 > 2) {
        // 文件不能大于2G
        this.form.videoUrl = ''
        this.$message.warning('文件大小不能超过2G')
        setTimeout(() => {
          this.$refs.uploaderRef.uploader.removeFile(file)
        }, 0)
        return false
      }
      this.computeMD5(file)
    }
  }
}

5、在父组件中调用上传方法

点击查看代码
 <hr-upload
          name="remote"
          :chunkSize="10 * 1024 * 1024"
          :action="action"
          ref="upload"
          @onFileError="onFileError"
          @needMerger="needMerger"
        ></hr-upload>

this.$refs.upload.$refs.uploaderRef.files[0].resume()

6、预览

标签:vue,const,uploader,simple,params,file,md5,上传,chunkSize
来源: https://www.cnblogs.com/mengqc1995/p/15716584.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有