当前位置:   article > 正文

vue-simple-uploader 的使用(学习笔记)

vue-simple-uploader

1.背景:  vue-simple-uploader 用于进行文件夹的上传,且项目要支持上传大文件,elementUI并不支持上传文件夹,所以使用vue-simple-uploader。

2.特点:

3.vue-simple-uploader的安装: 

  1. 命令:npm install vue-simple-uploader --save
  2. 在main.js 中
    1. import uploader from 'vue-simple-uploader';
    2. Vue.use(uploader);
  3. 配置选项:
    1. options: {
    2. target: 'http://localhost:8080', // SpringBoot后台接收文件夹数据的接口
    3. simultaneousUploads: 10, // 支持同时上传数量
    4. autoStart: false, // 自动上传
    5. panelShow: false,
    6. allowDuplicateUploads: false, // 上传过得文件不可以再上传
    7. testChunks: false, // 是否分片-不分片
    8. chunkSize: '102400000000',//块大小
    9. //query参数是带有数据的post的额外参数,policy、OSSAccessKeyId和signature是获取到的后端签名返回,success_action_status需设置为 200
    10. query: (file) => {
    11. return {
    12. name: file.name,
    13. key: file.key,
    14. policy,
    15. OSSAccessKeyId: accessId,
    16. signature,
    17. success_action_status: 200,
    18. };
    19. },
    20. }

4.常用的方法 

  • fileAdded(file, event): 用于文件的验证,可以判断可接受的文件类型,不支持的格式会返回false,拒绝上传,添加文件时,同样也可使用浏览器的event对象;
  • filesAdded(files, fileList, event): 和.fileAdded相同,不过是用于多文件的验证;
  • fileSuccess(rootFile, file, message, chunk):完成一个特定的文件上传,rootFile是根文件夹,file是要上传的文件对象,message是服务器返回的响应信息,第四个参数' chunk '是' Uploader.Chunk '的实例;

  • complete():所有的文件都上传成功;

  • fileProgress(rootFile): 获取文件上传的进度,rootFile是所有文件;

  • fileError(rootFile, file, message, chunk):特定的文件上传失败,可在这个回调函数中给用户提示

5.使用:

        1.DOM部分

  1. <template>
  2. <!-- 上传器 -->
  3. <uploader ref='uploader' :options='options' :autoStart=false :file-status-text='fileStatusText'
  4. @file-added='onFileAdded' @file-success='onFileSuccess' @file-removed="filesRemove" @file-error='onFileError'
  5. class='uploader-ui'>
  6. <uploader-unsupport></uploader-unsupport>
  7. <uploader-drop>
  8. <div>
  9. <uploader-btn id='global-uploader-btn' :attrs='attrs' ref='uploadBtn'>
  10. 选择文件
  11. <i class='el-icon-upload el-icon--right'></i>
  12. </uploader-btn>
  13. </div>
  14. </uploader-drop>
  15. <uploader-list></uploader-list>
  16. </uploader>
  17. </template>

        2.script部分

        

  1. <script>
  2. export default {
  3. data() {
  4. return {
  5. options: {
  6. //目标上传 URL,默认POST
  7. target: process.env.VUE_APP_BASE_URL + '/uploader/chunk',
  8. //分块大小(单位:字节)
  9. chunkSize: '2048000',
  10. //上传文件时文件内容的参数名,对应chunk里的Multipart对象名,默认对象名为file
  11. fileParameterName: 'upfile',
  12. //失败后最多自动重试上传次数
  13. maxChunkRetries: 3,
  14. changeOrigin: true,
  15. //是否开启服务器分片校验,对应GET类型同名的target URL
  16. testChunks: true,
  17. headers: { 'Authorization': 'Bearer ' + localStorage.getItem('token') },
  18. /*
  19. 服务器分片校验函数,判断秒传及断点续传,传入的参数是Uploader.Chunk实例以及请求响应信息
  20. reponse码是successStatuses码时,才会进入该方法
  21. reponse码如果返回的是permanentErrors 中的状态码,不会进入该方法,直接进入onFileError函数 ,并显示上传失败
  22. reponse码是其他状态码,不会进入该方法,正常走标准上传
  23. checkChunkUploadedByResponse函数直接return true的话,不再调用上传接口
  24. */
  25. checkChunkUploadedByResponse: function (chunk, response_msg) {
  26. let objMessage = JSON.parse(response_msg);
  27. if (objMessage.skipUpload) {
  28. return true;
  29. }
  30. return (objMessage.uploadedChunks || []).indexOf(chunk.offset + 1) >= 0;
  31. }
  32. },
  33. attrs: {
  34. accept: ACCEPT_CONFIG.getAll()
  35. },
  36. fileStatusText: {
  37. success: '上传成功',
  38. error: '上传失败',
  39. uploading: '上传中',
  40. paused: '暂停',
  41. waiting: '等待上传'
  42. }
  43. };
  44. },
  45. methods: {
  46. onFileAdded(file) {
  47. this.computeMD5(file);
  48. },
  49. /*
  50. 第一个参数 rootFile 就是成功上传的文件所属的根 Uploader.File 对象,它应该包含或者等于成功上传文件;
  51. 第二个参数 file 就是当前成功的 Uploader.File 对象本身;
  52. 第三个参数就是 message 就是服务端响应内容,永远都是字符串;
  53. 第四个参数 chunk 就是 Uploader.Chunk 实例,它就是该文件的最后一个块实例,如果你想得到请求响应码的话,chunk.xhr.status就是
  54. */
  55. onFileSuccess(rootFile, file, response, chunk) {
  56. //refProjectId为预留字段,可关联附件所属目标,例如所属档案,所属工程等
  57. file.refProjectId = '123456789';
  58. console.log('::::', file);
  59. let data = file
  60. data.filename = file.name
  61. data.identifier = file.uniqueIdentifier
  62. data.totalSize = file.size
  63. data.alluxioPath = this.sendContent.alluxioPath
  64. data.userStorageId = this.sendContent.id
  65. console.log('file', file, data)
  66. mergeFile(data).then(res => {
  67. console.log('23342', res)
  68. console.log('父组件', this.$parent)
  69. // if (res.code === 415) {
  70. // console.log('合并操作未成功,结果码:' + res.code);
  71. // }
  72. if (res.code == 200) {
  73. if (this.sendContent.idArray && this.sendContent.idArray.length > 0) {
  74. this.sendContent.idArray.forEach((item) => {
  75. // this.$parent.refreshList(item)
  76. console.log('aaaaaaaaa',item)
  77. this.$emit('refresh', item)
  78. this.$emit('getFather')
  79. })
  80. this.$message.success(res.message)
  81. }
  82. } else {
  83. this.$message.error(res.message)
  84. }
  85. })
  86. // .catch(function (error) {
  87. // console.log('合并后捕获的未知异常:' + error);
  88. // });
  89. },
  90. filesRemove(file) {
  91. // this.$refs.uploader.pause();
  92. file.paused = true
  93. let data = file
  94. data.filename = file.name
  95. data.identifier = file.uniqueIdentifier
  96. data.totalSize = file.size
  97. data.alluxioPath = this.sendContent.alluxioPath
  98. data.userStorageId = this.sendContent.id
  99. deleteMkFile(data).then((res) => {
  100. console.log('delete', res)
  101. if (res.code == 200) {
  102. this.$message.success(res.msg)
  103. } else {
  104. this.$message.error(res.msg)
  105. }
  106. })
  107. // const uploaderInstance = this.$refs.uploader.uploader;
  108. // let temp = uploaderInstance.fileList.findIndex(e => e.uniqueIdentifier === file.uniqueIdentifier)
  109. // if (temp > -1) {
  110. // uploaderInstance.fileList[temp].cancel(); //这句代码是删除所选上传文件的关键
  111. // }
  112. },
  113. onFileError(rootFile, file, response, chunk) {
  114. console.log('上传完成后异常信息:' + response);
  115. },
  116. /**
  117. * 计算md5,实现断点续传及秒传
  118. * @param file
  119. */
  120. computeMD5(file) {
  121. file.pause();
  122. //单个文件的大小限制2G
  123. let fileSizeLimit = 2 * 1024 * 1024 * 1024;
  124. console.log('文件大小:' + file.size);
  125. console.log('限制大小:' + fileSizeLimit);
  126. console.log('alluxioPath' + this.sendContent.alluxioPath);
  127. // if (file.size > fileSizeLimit) {
  128. // this.$message({
  129. // showClose: true,
  130. // message: '文件大小不能超过2G'
  131. // });
  132. // file.cancel();
  133. // }
  134. let fileReader = new FileReader();
  135. let time = new Date().getTime();
  136. let blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice;
  137. let currentChunk = 0;
  138. const chunkSize = 10 * 1024 * 1000;
  139. let chunks = Math.ceil(file.size / chunkSize);
  140. let spark = new SparkMD5.ArrayBuffer();
  141. //由于计算整个文件的Md5太慢,因此采用只计算第1块文件的md5的方式
  142. let chunkNumberMD5 = 1;
  143. loadNext();
  144. fileReader.onload = (e => {
  145. spark.append(e.target.result);
  146. if (currentChunk < chunkNumberMD5) {
  147. loadNext();
  148. } else {
  149. let md5 = spark.end();
  150. file.uniqueIdentifier = md5;
  151. file.resume();
  152. console.log(`MD5计算完毕:${file.name} \nMD5:${md5} \n分片:${chunks} 大小:${file.size} 用时:${new Date().getTime() - time} ms`);
  153. }
  154. });
  155. fileReader.onerror = function () {
  156. this.error(`文件${file.name} 读取出错,请检查该文件`);
  157. file.cancel();
  158. };
  159. function loadNext() {
  160. let start = currentChunk * chunkSize;
  161. let end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize;
  162. fileReader.readAsArrayBuffer(blobSlice.call(file.file, start, end));
  163. currentChunk++;
  164. console.log('计算第' + currentChunk + '块');
  165. }
  166. },
  167. close() {
  168. this.uploader.cancel();
  169. },
  170. error(msg) {
  171. this.$notify({
  172. title: '错误',
  173. message: msg,
  174. type: 'error',
  175. duration: 2000
  176. });
  177. }
  178. }
  179. };
  180. </script>

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号