Maison > interface Web > js tutoriel > le corps du texte

Comment implémenter la fonction de téléchargement de fichiers dans les tranches via Vue2.0 combinée avec webuploader (tutoriel détaillé)

亚连
Libérer: 2018-05-31 15:58:51
original
6155 Les gens l'ont consulté

Cet article présente principalement la fonction de Vue2.0 combinée avec webuploader pour implémenter le téléchargement de partage de fichiers. Il est très bon et a une valeur de référence. Les amis dans le besoin peuvent s'y référer

J'ai rencontré un partage de fichiers volumineux dans le. Projet Vue Concernant le problème de téléchargement, j'ai déjà utilisé webuploader, j'ai donc simplement combiné Vue2.0 avec webuploader pour encapsuler un composant de téléchargement vue, qui est plus confortable à utiliser.

Téléchargez-le simplement. Pourquoi devez-vous vous donner tant de mal et utiliser le téléchargement en plusieurs parties ?

Combinant fragmentation et concurrence, un fichier volumineux est divisé en plusieurs blocs et téléchargé simultanément, ce qui améliore considérablement la vitesse de téléchargement des fichiers volumineux.

Lorsque des problèmes de réseau provoquent des erreurs de transmission, seuls les fragments erronés doivent être retransmis, pas l'intégralité du fichier. De plus, la transmission fragmentée peut suivre la progression du téléchargement plus en temps réel.

L'interface après implémentation :

Il y a principalement deux fichiers, le composant de téléchargement encapsulé et la page d'interface utilisateur spécifique. Le code du composant de téléchargement est répertorié ci-dessous. Les codes de ces deux pages sont mis sur github : https://github.com/shady-xia/Blog/tree/master/vue-webuploader.

Introduire webuploader dans le projet

1. Introduisez d'abord jquery dans le système (le plug-in est basé sur jq, c'est une arnaque. !), si ce n'est pas le cas, Si vous savez où le mettre, mettez-le dans index.html.

2. Téléchargez Uploader.swf et webuploader.min.js depuis le site officiel et placez-les dans le répertoire statique du projet ; introduisez webuploader.min.js dans index.html.

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

Points à noter :

1 Dans le composant vue, introduisez import &#39;./webuploader&#39; à webuploader , l'erreur ; Les propriétés "appelant", "appelé" et "arguments" ne sont pas accessibles en mode strict...' seront signalées parce que votre babel utilise le mode strict et que l'utilisation de l'appelant est interdite. Vous pouvez donc introduire directement index.html dans webuploader.js , ou résoudre manuellement le problème « use strict » dans babel.

Encapsuler les composants Vue basés sur webuploader

Le composant packagé upload.vue est le suivant. L'interface peut être étendue en fonction d'une activité spécifique.

Remarque : la fonction et l'interface utilisateur sont séparées. Ce composant encapsule les fonctions de base et ne fournit pas d'interface utilisateur implémentée sur des pages spécifiques.

<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>
Copier après la connexion

Utilisez le composant de téléchargement encapsulé

pour créer une nouvelle page. L'exemple d'utilisation est le suivant :

<🎜. >ui doit y aller par vous-même. Le code approximatif peut être trouvé ici.

<vue-upload
    ref="uploader"
    url="xxxxxx"
    uploadButton="#filePicker"
    multiple
    @fileChange="fileChange"
    @progress="onProgress"
    @success="onSuccess"
></vue-upload>
Copier après la connexion

Le principe et le processus de fragmentation

Lorsque nous téléchargeons un fichier volumineux, il sera fragmenté par le plug-in. La requête ajax est la suivante :

1. Les requêtes de téléchargement multiples sont des requêtes fragmentées. Le gros fichier est divisé en plusieurs petites parties et livré au serveur une à la fois. 🎜>

2. Une fois la fragmentation terminée, c'est-à-dire une fois le téléchargement terminé, une demande de fusion doit être transmise au serveur pour permettre au serveur de combiner plusieurs fichiers fragmentés en un seul fichier

Fragmentation


Vous pouvez voir que plusieurs demandes de téléchargement ont été initiées, jetons un œil aux paramètres spécifiques envoyés par téléchargement :

Le guid dans la première configuration (

) et le access_token dans la deuxième configuration sont ce que nous transmettons formData dans la configuration webuploader, c'est-à-dire les paramètres transmis au serveur

content-disposition Les configurations suivantes sont le contenu du fichier, l'identifiant, le nom, le type, la taille , etc.

où chunks est le nombre total de fragments et chunk est le nombre actuel de fragments. Ils sont respectivement 12 et 9 sur la photo. Lorsque vous voyez une demande de téléchargement avec le chunk 11, cela signifie qu'il s'agit de la dernière demande de téléchargement.

FusionnerAprès le partitionnement, les fichiers n'ont pas été intégrés et les données ressemblent à ce qui suit :

Après avoir terminé le sharding, le travail n'est en fait pas encore terminé. Nous devons envoyer une autre requête ajax au serveur, lui disant de fusionner les différents fragments que nous avons téléchargés dans un fichier complet.

Comment puis-je savoir que le téléchargement en plusieurs parties est terminé et quand dois-je le fusionner ?

Le plug-in a un événement

, qui contient deux paramètres, un fichier et une réponse renvoyés par l'arrière-plan ; lorsque tous les fragments sont téléchargés, l'événement sera déclenché, webuploader uploadSuccess we Vous pouvez utiliser les champs renvoyés par le serveur pour déterminer s'il faut fusionner.

Par exemple, si needMerge est renvoyé en arrière-plan et que nous voyons que c'est vrai, nous pouvons envoyer une demande de fusion.

Problèmes connus

Lors de la pause et de la poursuite du téléchargement d'un seul fichier, un bug dans ce plug-in a été découvert :

1 . Lorsque threads>1 est défini et que la fonction de téléchargement de fichier unique est utilisée, c'est-à-dire lorsque la méthode d'arrêt est passée dans le fichier, une erreur Uncaught TypeError: Cannot read property 'file' of undefined

sera signalée. comme suit : en effet, la pause est destinée à permettre au fichier suivant de continuer à être transféré, le flux de fichiers en pause sera extrait du pool actuel. Une boucle est faite ici, et v n'est pas défini lors de la dernière boucle.

2. Définissez les fils de discussion sur 1 et ils peuvent être mis en pause normalement, mais le téléchargement après la pause échouera.

Le principe est le même que le précédent. Pendant la pause, tous les flux de fichiers en cours sont placés dans le pool. Lorsque le téléchargement du fichier commence, le pool en cours sera vérifié, et à ce moment là. il n’y a aucun flux de fichiers précédemment mis en pause.

S'il s'agit de mettre en pause et de reprendre tous les fichiers dans leur ensemble, la fonction est normale.

J'ai compilé ce qui précède pour vous, j'espère que cela vous sera utile à l'avenir.

Articles connexes :

Compréhension approfondie du module Node

Un résumé de 10 techniques avancées d'utilisation de la console pour déboguer

À propos de la différence entre v-if et v-show dans vuejs et du problème que v-show ne fonctionne pas

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
web
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal