Heim  >  Artikel  >  Web-Frontend  >  So implementieren Sie die Datei-Upload-Funktion in Slices über Vue2.0 in Kombination mit Webuploader (ausführliches Tutorial)

So implementieren Sie die Datei-Upload-Funktion in Slices über Vue2.0 in Kombination mit Webuploader (ausführliches Tutorial)

亚连
亚连Original
2018-05-31 15:58:516071Durchsuche

In diesem Artikel wird hauptsächlich die Funktion von Vue2.0 in Kombination mit dem Webuploader zum Implementieren des Datei-Sharding-Uploads vorgestellt. Es ist sehr gut und hat Referenzwert.

Auf großes Datei-Sharding gestoßen Vue-Projekt Was das Upload-Problem betrifft, habe ich zuvor Webuploader verwendet, daher habe ich einfach Vue2.0 mit Webuploader kombiniert, um eine Vue-Upload-Komponente zu kapseln, die komfortabler zu verwenden ist.

Laden Sie es einfach hoch. Warum sollten Sie sich die Mühe machen, es in Teilen hochzuladen?

Durch die Kombination von Fragmentierung und Parallelität wird eine große Datei in mehrere Blöcke unterteilt und gleichzeitig hochgeladen, was die Upload-Geschwindigkeit großer Dateien erheblich verbessert.

Wenn Netzwerkprobleme Übertragungsfehler verursachen, müssen nur die fehlerhaften Fragmente erneut übertragen werden, nicht die gesamte Datei. Darüber hinaus kann durch die fragmentierte Übertragung der Upload-Fortschritt in Echtzeit verfolgt werden.

Die Schnittstelle nach der Implementierung:

Es gibt hauptsächlich zwei Dateien, die gekapselte Upload-Komponente und die spezifische UI-Seite. Der Code der Upload-Komponente ist unten aufgeführt. Die Codes dieser beiden Seiten werden auf Github bereitgestellt: https://github.com/shady-xia/Blog/tree/master/vue-webuploader.

Führen Sie den Webuploader in das Projekt ein

Führen Sie zuerst jquery in das System ein (das Plug-in basiert auf jq, es ist ein Betrug). !), wenn Sie nicht wissen, wo Sie es ablegen sollen, fügen Sie es in index.html ein.

2. Laden Sie Uploader.swf und webuploader.min.js von der offiziellen Website herunter und legen Sie sie im statischen Verzeichnis des Projekts ab.

(无需单独再引入 webuploader.css ,因为没有几行css,我们可以复制到vue组件中。)
<script src="/static/lib/jquery-2.2.3.min.js"></script>
<script src="/static/lib/webuploader/webuploader.min.js"></script>

Zu beachtende Punkte:

1. Führen Sie in der Vue-Komponente import './webuploader' bis webuploader ein. Auf die Eigenschaften „callee“ und „arguments“ kann im strikten Modus nicht zugegriffen werden. Dies liegt daran, dass Ihr Babel den strikten Modus verwendet und die Verwendung von caller im strikten Modus verboten ist. Sie können also index.html direkt in webuploader.js einführen oder das Problem der strikten Verwendung in Babel manuell lösen.

Kapseln Sie Vue-Komponenten basierend auf dem Webuploader

Die gepackte Komponente upload.vue ist wie folgt. Die Schnittstelle kann je nach Unternehmen erweitert werden.

Hinweis: Funktion und Benutzeroberfläche sind getrennt. Diese Komponente kapselt grundlegende Funktionen und stellt keine Benutzeroberfläche bereit, die auf bestimmten Seiten implementiert ist.

<template>
 <p class="upload">
 </p>
</template>
<script>
 export default {
  name: &#39;vue-upload&#39;,
  props: {
   accept: {
    type: Object,
    default: null,
   },
   // 上传地址
   url: {
    type: String,
    default: &#39;&#39;,
   },
   // 上传最大数量 默认为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: &#39;&#39;,
   },
  },
  data() {
   return {
    uploader: null
   };
  },
  mounted() {
   this.initWebUpload();
  },
  methods: {
   initWebUpload() {
    this.uploader = WebUploader.create({
     auto: true, // 选完文件后,是否自动上传
     swf: &#39;/static/lib/webuploader/Uploader.swf&#39;, // swf文件路径
     server: this.url, // 文件接收服务端
     pick: {
      id: this.uploadButton,  // 选择文件的按钮
      multiple: this.multiple, // 是否多文件上传 默认false
      label: &#39;&#39;,
     },
     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(&#39;fileQueued&#39;, (file) => {
     this.$emit(&#39;fileChange&#39;, file);
    });
    this.uploader.on(&#39;uploadStart&#39;, (file) => {
     // 在这里可以准备好formData的数据
     //this.uploader.options.formData.key = this.keyGenerator(file);
    });
    // 文件上传过程中创建进度条实时显示。
    this.uploader.on(&#39;uploadProgress&#39;, (file, percentage) => {
     this.$emit(&#39;progress&#39;, file, percentage);
    });
    this.uploader.on(&#39;uploadSuccess&#39;, (file, response) => {
     this.$emit(&#39;success&#39;, file, response);
    });
    this.uploader.on(&#39;uploadError&#39;, (file, reason) => {
     console.error(reason);
     this.$emit(&#39;uploadError&#39;, file, reason);
    });
    this.uploader.on(&#39;error&#39;, (type) => {
     let errorMessage = &#39;&#39;;
     if (type === &#39;F_EXCEED_SIZE&#39;) {
      errorMessage = `文件大小不能超过${this.fileSingleSizeLimit / (1024 * 1000)}M`;
     } else if (type === &#39;Q_EXCEED_NUM_LIMIT&#39;) {
      errorMessage = &#39;文件上传已达到最大上限数&#39;;
     } else {
      errorMessage = `上传出错!请检查后重新上传!错误代码${type}`;
     }
     console.error(errorMessage);
     this.$emit(&#39;error&#39;, errorMessage);
    });
    this.uploader.on(&#39;uploadComplete&#39;, (file, response) => {
     this.$emit(&#39;complete&#39;, 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 &#39;text&#39;:
      return {
       title: &#39;Texts&#39;,
       exteensions: &#39;doc,docx,xls,xlsx,ppt,pptx,pdf,txt&#39;,
       mimeTypes: &#39;.doc,docx,.xls,.xlsx,.ppt,.pptx,.pdf,.txt&#39;
      };
      break;
     case &#39;video&#39;:
      return {
       title: &#39;Videos&#39;,
       exteensions: &#39;mp4&#39;,
       mimeTypes: &#39;.mp4&#39;
      };
      break;
     case &#39;image&#39;:
      return {
       title: &#39;Images&#39;,
       exteensions: &#39;gif,jpg,jpeg,bmp,png&#39;,
       mimeTypes: &#39;.gif,.jpg,.jpeg,.bmp,.png&#39;
      };
      break;
     default: return accept
    }
   },
  },
 };
</script>
<style lang="scss">
// 直接把官方的css粘过来就行了
</style>

Verwenden Sie die gekapselte Upload-Komponente

, um eine neue Seite zu erstellen:

ui muss selbst umgesetzt werden. Den ungefähren Code finden Sie hier.

<vue-upload
    ref="uploader"
    url="xxxxxx"
    uploadButton="#filePicker"
    multiple
    @fileChange="fileChange"
    @progress="onProgress"
    @success="onSuccess"
></vue-upload>

Das Prinzip und der Prozess der Fragmentierung

Wenn wir eine große Datei hochladen, wird sie durch das Plug-in fragmentiert und die Die Ajax-Anfrage lautet wie folgt:

1. Mehrere Upload-Anfragen sind alle fragmentierte Anfragen. Die große Datei wird in mehrere kleine Teile aufgeteilt und einzeln an den Server übermittelt

2. Fragmentierung Nach Abschluss, also nach Abschluss des Uploads, muss eine Zusammenführungsanforderung an den Server übergeben werden, damit der Server mehrere fragmentierte Dateien zu einer Datei zusammenfassen kann
Fragmentierung

Sie können sehen, dass mehrere Upload-Anfragen initiiert wurden. Werfen wir einen Blick auf die spezifischen Parameter, die per Upload gesendet werden:

Die Anleitung in der ersten Konfiguration ( content-disposition ) und das access_token in der zweiten Konfiguration werden von uns über den Webuploader konfiguriert. Die formData in sind die an den Server übergebenen Parameter

Die folgenden Konfigurationen sind Dateiinhalt, ID, Name, Typ, Größe usw.

wobei Chunks die Gesamtzahl der Fragmente und Chunk die aktuelle Anzahl der Fragmente ist. Auf dem Bild sind es die Nummern 12 und 9. Wenn Sie eine Upload-Anfrage mit Block 11 sehen, bedeutet dies, dass dies die letzte Upload-Anfrage ist.

Zusammenführen

Nach dem Sharding wurden die Dateien nicht integriert und die Daten sehen wie folgt aus:

Nach Abschluss des Shardings ist die Arbeit eigentlich noch nicht abgeschlossen. Wir müssen eine weitere Ajax-Anfrage an den Server senden und ihn auffordern, die mehreren von uns hochgeladenen Shards zu einer vollständigen Datei zusammenzuführen.

Woher weiß ich, dass der mehrteilige Upload abgeschlossen ist und wann sollte ich ihn zusammenführen?

webuploaderDas Plug-in verfügt über ein Ereignis uploadSuccess , das zwei Parameter enthält: Datei und Antwort, die vom Hintergrund zurückgegeben werden. Wenn alle Fragmente hochgeladen sind, wird das Ereignis ausgelöst,

we Sie können die vom Server zurückgegebenen Felder verwenden, um zu bestimmen, ob eine Zusammenführung erfolgen soll.

Wenn beispielsweise needMerge im Hintergrund zurückgegeben wird und wir sehen, dass es wahr ist, können wir eine Zusammenführungsanforderung senden.

Bekannte Probleme

Beim Anhalten und Fortsetzen des Hochladens einer einzelnen Datei wurde ein Fehler in diesem Plug-in entdeckt:

1 . Wenn threads>1 festgelegt ist und die Funktion zum Hochladen einzelner Dateien verwendet wird, d. h. wenn die Stoppmethode in der Datei übergeben wird, wird ein Fehler Uncaught TypeError: Cannot read property 'file' of undefined

gemeldet wie folgt: Dies liegt daran, dass die Pause dazu dient, die Übertragung der nächsten Datei fortzusetzen. Dadurch wird der angehaltene Dateistream aus dem aktuellen Pool entfernt. Hier wird eine Schleife erstellt und v ist während der letzten Schleife undefiniert.

2. Setzen Sie Threads auf 1 und es kann normal angehalten werden, aber das Hochladen nach dem Anhalten schlägt fehl.

Das Prinzip ist das gleiche wie beim vorherigen. Während der Pause werden alle aktuellen Dateistreams in den Pool eingefügt. Wenn die Datei hochgeladen wird, wird der aktuelle Pool überprüft Es gibt keine zuvor angehaltenen Dateistreams.

Wenn es darum geht, alle Dateien als Ganzes anzuhalten und fortzusetzen, ist die Funktion normal.

Ich habe das Obige für Sie zusammengestellt und hoffe, dass es Ihnen in Zukunft hilfreich sein wird.

Verwandte Artikel:

Detailliertes Verständnis des Node-Moduls

Eine Zusammenfassung von 10 fortgeschrittenen Techniken zum Debuggen mit der Konsole

Über den Unterschied zwischen v-if und v-show in Vuejs und das Problem, dass v-show nicht funktioniert

Das obige ist der detaillierte Inhalt vonSo implementieren Sie die Datei-Upload-Funktion in Slices über Vue2.0 in Kombination mit Webuploader (ausführliches Tutorial). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn