vue vue-simple-uploader 前端的簡單使用


前言

因為項目需要上傳大文件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、預覽


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM