Vue 2.0 웹 uploader 와 결합 하여 파일 분할 업로드 기능 실현

Vue 프로젝트 에서 큰 파일 을 나 누 어 업로드 하 는 문제 가 발생 했 습 니 다.전에 webuploader 를 사용 한 적 이 있 습 니 다.아예 Vue 2.0 과 webuploader 를 결합 하여 사용 하 였 습 니 다.vue 의 업로드 구성 요 소 를 봉 하여 사용 하 는 것 도 비교적 편안 합 니 다.
올 리 면 올 려.왜 그렇게 귀 찮 게 만들어 서 나 눠 서 올 려?
블록 버스터 와 병발 을 결합 하여 하나의 큰 파일 을 여러 블록 으로 나 누 어 동시에 업로드 하여 큰 파일 의 업로드 속 도 를 크게 향상 시킨다.
네트워크 문제 로 전송 오류 가 발생 했 을 때 전체 파일 이 아 닌 오 류 를 다시 전송 해 야 합 니 다.또한 필름 전송 은 업로드 진 도 를 더욱 실시 간 으로 추적 할 수 있다.
실현 후의 인터페이스:
 
주로 두 개의 파일 입 니 다.봉 인 된 업로드 구성 요소 와 구체 적 인 ui 페이지 입 니 다.업로드 구성 요소 코드 아래 에 열 거 됩 니 다.이 두 페이지 의 코드 는 github 에 올 려 졌 다.https://github.com/shady-xia/Blog/tree/master/vue-webuploader.
프로젝트 에 webuploader 도입
1.먼저 시스템 에 jquery 를 도입 합 니 다(플러그 인 은 jq 기반,아버지!).어디 에 놓 을 지 모 르 면 index.html 에 넣 으 세 요.
2.홈 페이지 에서 Uploader.swf webuploader.min.js 을 다운로드 하면 프로젝트 정적 디 렉 터 리 static 아래 에 놓 을 수 있 습 니 다.index.html 에 webuploader.min.js 를 도입 합 니 다.

(        webuploader.css ,      css,       vue   。)
<script src="/static/lib/jquery-2.2.3.min.js"></script>
<script src="/static/lib/webuploader/webuploader.min.js"></script>
주의해 야 할 점:
1.vue 구성 요소 에서 import './webuploader' 을 통과 합 니 다.webuploader 방식 을 도입 하면'caller','callee',and'arguments'properties may not be accessed on strict mode...'의 오 류 를 보고 합 니 다.이것 은 당신 의 babel 이 엄격 한 모드 를 사 용 했 기 때 문 입 니 다.caller 는 엄격 한 모드 에서 사용 할 수 없습니다.그래서 index.htmlwebuploader.js 을 직접 도입 하거나 babel 에서'use strict'문 제 를 수 동 으로 해결 할 수 있 습 니 다.
웹 uploader 기반 패키지 Vue 구성 요소
봉 인 된 구성 요소 upload.vue 는 다음 과 같 습 니 다.인 터 페 이 스 는 구체 적 인 업무 에 따라 확장 할 수 있 습 니 다.
메모:기능 과 ui 가 분리 되 어 있 습 니 다.이 구성 은 기본 적 인 기능 을 봉 인 했 고 ui 를 제공 하지 않 았 습 니 다.ui 는 구체 적 인 페이지 에서 이 루어 집 니 다.

<template>
 <div class="upload">
 </div>
</template>
<script>
 export default {
  name: 'vue-upload',
  props: {
   accept: {
    type: Object,
    default: null,
   },
   //     
   url: {
    type: String,
    default: '',
   },
   //           100
   fileNumLimit: {
    type: Number,
    default: 100,
   },
   //        2M
   fileSingleSizeLimit: {
    type: Number,
    default: 2048000,
   },
   //           ,   token,key 
   formData: {
    type: Object,
    default: null
   },
   //   formData    key,       ,           
   keyGenerator: {
    type: Function,
    default(file) {
     const currentTime = new Date().getTime();
     const key = `${currentTime}.${file.name}`;
     return key;
    },
   },
   multiple: {
    type: Boolean,
    default: false,
   },
   //     ID
   uploadButton: {
    type: String,
    default: '',
   },
  },
  data() {
   return {
    uploader: null
   };
  },
  mounted() {
   this.initWebUpload();
  },
  methods: {
   initWebUpload() {
    this.uploader = WebUploader.create({
     auto: true, //      ,      
     swf: '/static/lib/webuploader/Uploader.swf', // swf    
     server: this.url, //        
     pick: {
      id: this.uploadButton,  //        
      multiple: this.multiple, //           false
      label: '',
     },
     accept: this.getAccept(this.accept), //         。
     threads: 3,
     fileNumLimit: this.fileNumLimit, //       
     //fileSingleSizeLimit: this.fileSingleSizeLimit, //            
     formData: this.formData, //       
     chunked: true,   //    
     chunkSize: 2048000, //    
     duplicate: true, //     
    });
    //              ,       
    this.uploader.on('fileQueued', (file) => {
     this.$emit('fileChange', file);
    });
    this.uploader.on('uploadStart', (file) => {
     //         formData   
     //this.uploader.options.formData.key = this.keyGenerator(file);
    });
    //                 。
    this.uploader.on('uploadProgress', (file, percentage) => {
     this.$emit('progress', file, percentage);
    });
    this.uploader.on('uploadSuccess', (file, response) => {
     this.$emit('success', file, response);
    });
    this.uploader.on('uploadError', (file, reason) => {
     console.error(reason);
     this.$emit('uploadError', file, reason);
    });
    this.uploader.on('error', (type) => {
     let errorMessage = '';
     if (type === 'F_EXCEED_SIZE') {
      errorMessage = `        ${this.fileSingleSizeLimit / (1024 * 1000)}M`;
     } else if (type === 'Q_EXCEED_NUM_LIMIT') {
      errorMessage = '            ';
     } else {
      errorMessage = `    !        !    ${type}`;
     }
     console.error(errorMessage);
     this.$emit('error', errorMessage);
    });
    this.uploader.on('uploadComplete', (file, response) => {
     this.$emit('complete', file, response);
    });
   },
   upload(file) {
    this.uploader.upload(file);
   },
   stop(file) {
    this.uploader.stop(file);
   },
   //          
   cancelFile(file) {
    this.uploader.cancelFile(file);
   },
   //         
   removeFile(file, bool) {
    this.uploader.removeFile(file, bool);
   },
   getAccept(accept) {
    switch (accept) {
     case 'text':
      return {
       title: 'Texts',
       exteensions: 'doc,docx,xls,xlsx,ppt,pptx,pdf,txt',
       mimeTypes: '.doc,docx,.xls,.xlsx,.ppt,.pptx,.pdf,.txt'
      };
      break;
     case 'video':
      return {
       title: 'Videos',
       exteensions: 'mp4',
       mimeTypes: '.mp4'
      };
      break;
     case 'image':
      return {
       title: 'Images',
       exteensions: 'gif,jpg,jpeg,bmp,png',
       mimeTypes: '.gif,.jpg,.jpeg,.bmp,.png'
      };
      break;
     default: return accept
    }
   },
  },
 };
</script>
<style lang="scss">
//       css      
</style>
봉 인 된 업로드 구성 요소 사용 하기
새 페이지,사용 예 는 다음 과 같 습 니 다.
ui 는 스스로 실현 해 야 한다.대충 코드 여기 눌 러 도 돼 요.

<vue-upload
    ref="uploader"
    url="xxxxxx"
    uploadButton="#filePicker"
    multiple
    @fileChange="fileChange"
    @progress="onProgress"
    @success="onSuccess"
></vue-upload>
분 편의 원리 와 절차
큰 파일 을 업로드 할 때 플러그 인 에 의 해 분 리 됩 니 다.ajax 는 다음 과 같이 요청 합 니 다.
 
1.여러 개의 upload 요청 은 모두 필름 분할 요청 으로 큰 파일 을 여러 개의 작은 부분 으로 나 누 어 한 번 에 서버 에 전달 합 니 다.
2.분할 완료 후,upload 완료 후 서버 에 merge 요청 을 전달 하여 서버 가 여러 개의 분할 파일 을 하나의 파일 로 합성 하도록 해 야 합 니 다.
조각 을 나누다
여러 번 upload 요청 을 한 것 을 볼 수 있 습 니 다.upload 가 보 낸 구체 적 인 인 인 자 를 살 펴 보 겠 습 니 다.
 
첫 번 째 설정( content-disposition )의 guid 와 두 번 째 설정 의 accesstoken,웹 uploader 설정 에 있 는 formData,즉 서버 에 전달 하 는 인자 입 니 다.
뒤의 몇 가지 설정 은 파일 내용,id,name,type,size 등 입 니 다.
그 중에서 chunks 는 총 분 편수 이 고 chunk 는 현재 몇 번 째 분 편수 이다.사진 속 에는 각각 12 와 9 가 담 겨 있다.chunk 가 11 의 upload 요청 을 보 았 을 때 마지막 upload 요청 입 니 다.
합치다
조각 을 나 눈 후에 파일 이 아직 통합 되 지 않 았 습 니 다.데 이 터 는 아래 와 같 습 니 다.
 
분 편 을 마 친 후에 사실은 일이 아직 끝나 지 않 았 습 니 다.우 리 는 ajax 요청 을 서버 에 보 내 서 우리 가 올 린 몇 개의 분 편 을 하나의 완전한 파일 로 통합 하 라 고 알려 야 합 니 다.
나 눠 서 올 렸 는 지 어떻게 알 아?내 가 언제 합병 할 거 야?webuploader 플러그 인 은 uploadSuccess 이벤트 가 있 습 니 다.두 개의 매개 변수,file 과 배경 에서 돌아 오 는 response 를 포함 합 니 다.모든 필름 업로드 가 완료 되면 이 사건 이 발생 합 니 다.
우 리 는 서버 가 되 돌아 오 는 필드 를 통 해 합병 여 부 를 판단 할 수 있다.
예 를 들 어 배경 이 needMerge 로 돌 아 왔 습 니 다.우 리 는 그것 이 true 라 는 것 을 보 았 을 때 합병 요청 을 보 낼 수 있 습 니 다.
 
존재 하 는 기지 의 문제
단일 파일 을 일시 정지 하고 계속 업로드 할 때 이 플러그 인의 bug 를 발 견 했 습 니 다.
1.설 정 된 threads>1 은 단일 파일 업로드 기능,즉 stop 방법 으로 file 에 들 어 갈 때 Uncaught TypeError: Cannot read property 'file' of undefined 을 잘못 보고 합 니 다.
오류 의 원본 코드 는 다음 과 같 습 니 다.일시 정지 시 다음 파일 을 계속 전송 하기 위해 현재 pool 풀 에서 pop 을 일시 정지 한 파일 흐름 을 떨 어 뜨 립 니 다.여기 서 순환 을 했 습 니 다.마지막 순환 을 할 때 v 는 undefined 입 니 다.
 
2.설 정 된 threads 는 1 로 정상적으로 일시 정지 할 수 있 으 나 일시 정지 후 계속 업로드 하 는 것 은 실 패 했 습 니 다.
원 리 는 이전 과 마찬가지 로 일시 정지 시 현재 파일 을 pool 에 모든 pop 으로 흐 르 게 합 니 다.파일 이 upload 를 시작 할 때 당기 pool 을 검사 합 니 다.이 때 는 일시 정지 한 파일 흐름 이 없습니다.
모든 파일 에 대한 전체 일시 정지 와 계속 이 라면 기능 은 정상 입 니 다.
총결산
위 에서 말 한 것 은 편집장 님 께 서 소개 해 주신 Vue 2.0 과 webuploader 를 결합 하여 파일 분할 업로드 기능 을 실현 하 는 것 입 니 다.여러분 께 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 저 에 게 메 시 지 를 남 겨 주세요.편집장 님 께 서 신속하게 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!

좋은 웹페이지 즐겨찾기