基于vue-simple-uploader封装文件分片上传、秒传及断点续传的全局上传插件

1. 前言

之前公司要在管理系统中做一个全局上传插件,即切换各个页面的时候,上传界面还在并且上传不会受到影响,这在vue这种spa框架面前并不是什么难题。然而后端大佬说我们要实现片上传秒传以及断点续传的功能,听起来头都大了。

很久之前我写了一篇webuploader的文章,结果使用起来发现问题很多,且官方团队不再维护这个插件了, 经过多天调研及踩雷,最终决定基于vue-simple-uploader插件实现该功能,在项目中使用起来无痛且稳定。

如果你只是想实现基本的(非定制化的)上传功能,直接使用vue-simple-uploader,多读一下它的文档,不需要更多的二次封装
如果你只是想实现全局上传插件,也可以参照一下我的实现。
如果你用到了片上传、秒传及断点续传这些复杂的功能,恭喜你,这篇文章的重点就在于此。

本文源码在此:https://github.com/shady-xia/Blog/tree/master/vue-simple-uploader

基于vue-simple-uploader封装文件分片上传、秒传及断点续传的全局上传插件

2. 关于vue-simple-uploader

vue-simple-uploader是基于 simple-uploader.js 封装的vue上传插件。它的优点包括且不限于以下几种:

支持文件、多文件、文件夹上传;支持拖拽文件、文件夹上传

可暂停、继续上传

错误处理

支持“秒传”,通过文件判断服务端是否已存在从而实现“秒传”

分块上传

支持进度、预估剩余时间、出错自动重试、重传等操作

读这篇文章之前,建议先读一遍simple-uploader.js的文档,然后再读一下vue-simple-uploader的文档,了解一下各个参数的作用是什么,我在这里假定大家已经比较熟悉了。。
vue-simple-uploader文档

simple-uploader.js文档

安装:npm install vue-simple-uploader --save
使用:在main.js中:

import uploader from 'vue-simple-uploader' Vue.use(uploader) 3. 基于vue-simple-uploader封装全局上传组件

引入vue-simple-uploader后,我们开始封装全局的上传组件globalUploader.vue,代码比较长,就不整个放出来了,源码放到github上了,这里一步一步地讲解。

template部分如下,本人自定义了模板和样式,所以html部分比较长,css部分暂时不列出,大家可以根据自己的ui去更改,主要关注一下uploader这个组件的options参数及文件added、success、progress、error几个事件:

<template> <div> <!-- 上传 --> <uploader ref="uploader" :options="options" :autoStart="false" @file-added="onFileAdded" @file-success="onFileSuccess" @file-progress="onFileProgress" @file-error="onFileError"> <uploader-unsupport></uploader-unsupport> <uploader-btn :attrs="attrs" ref="uploadBtn">选择文件</uploader-btn> <uploader-list v-show="panelShow"> <div slot-scope="props" :class="{'collapse': collapse}"> <div> <h2>文件列表</h2> <div> <el-button @click="fileListShow" type="text" :title="collapse ? '展开':'折叠' "> <i :class="collapse ? 'icon-fullscreen': 'icon-minus-round'"></i> </el-button> <el-button @click="close" type="text" title="关闭"> <i></i> </el-button> </div> </div> <ul> <li v-for="file in props.fileList" :key="file.id"> <uploader-file :class="'file_' + file.id" ref="files" :file="file" :list="true"></uploader-file> </li> <div v-if="!props.fileList.length"><i></i> 暂无待上传文件</div> </ul> </div> </uploader-list> </uploader> </div> </template>

组件中的data部分

data() { return { options: { target: 'http://xxxxx/xx', // 目标上传 URL chunkSize: '2048000', //分块大小 fileParameterName: 'file', //上传文件时文件的参数名,默认file testChunks: true, //是否开启秒传 maxChunkRetries: 3, //最大自动失败重试上传次数 // 服务器分片校验,断点续传基础 checkChunkUploadedByResponse: function (chunk, message) { let objMessage = JSON.parse(message); if (objMessage.skipUpload) { return true; } return (objMessage.uploaded || []).indexOf(chunk.offset + 1) >= 0 }, headers: { // 在header中添加的验证,请根据实际业务来 Authorization: "Bearer " + Ticket.get().access_token }, }, attrs: { // 接受的文件类型,形如['.png', '.jpg', '.jpeg', '.gif', '.bmp'...] 这里我封装了一下 accept: ACCEPT_CONFIG.getAll() }, panelShow: false, //选择文件后,展示上传panel } },

全局引用:
在app.vue中引用,即作为全局的组件一直存在,只不过在不使用的时候把上传界面隐藏了

<global-uploader></global-uploader> 4. 文件上传流程概览

1. 点击按钮,触发文件上传操作:

(如果你做的不是全局上传的功能,而是直接点击上传,忽略这一步。)

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpfddw.html