插件使用手册:vue-simple-upload 上传插件[支持文件、文件夹上传]
前言
近期有一个项目需求是做一个 公司内部的 知识库 模块。要求实现文件、文件夹上传,以及后续的文档在线预览、下载、删除、新建空文件夹等类似于一个网盘的业务。搜索一圈,发现了这个插件,而且插件的参数事件信息也挺齐全,缺点就是貌似作者没有维护了,后续出现了bug只能自行解决。用于一个基本的文件、文件夹上传需求还是可以满足,使用的话还请自行思量。
简介
vue-simple-uploader 是基于 simple-uploader.js 和Vue结合做的一个上传组件,自带 UI,可覆盖、自定义。它支持文件、多文件、文件夹上传;支持拖拽文件、文件夹上传;可暂停、继续上传;支持秒传;上传队列管理,支持最大并发上传;分片上传;支持进度、预估剩余时间、出错自动重试、重传等操作。
查看演示:https://www.helloweba.net/demo/2020/vueuploader/#/
配置
安装:
npm install vue-simple-uploader --save
初始化,在main.js中添加如下代码:
import Vue from 'vue'
import uploader from 'vue-simple-uploader'
import App from './App.vue'
Vue.use(uploader)
使用
<template> <uploader :options="options" class="uploader-example"> <uploader-unsupport></uploader-unsupport> <uploader-drop> <p>Drop files here to upload or</p> <uploader-btn>select files</uploader-btn> <uploader-btn :attrs="attrs">select images</uploader-btn> <uploader-btn :directory="true">select folder</uploader-btn> </uploader-drop> <uploader-list></uploader-list> </uploader> </template> <script> export default { data () { return { options: { target: 'http://localhost:9000/upload', testChunks: false, chunkSize: 1024*1024*2, //1MB simultaneousUploads: 3, //并发上传数 headers: { 'access-token': 'abcd1234' }, query :{ code : 123 } }, attrs: { accept: 'image/*' } } } } </script> <style> .uploader-example { width: 880px; padding: 15px; margin: 40px auto 0; font-size: 12px; box-shadow: 0 0 10px rgba(0, 0, 0, .4); } .uploader-example .uploader-btn { margin-right: 4px; } .uploader-example .uploader-list { max-height: 440px; overflow: auto; overflow-x: hidden; overflow-y: auto; } </style>
传递参数
插件使用时,上传请求都会包含如下分块信息:
chunkNumber
: 当前块的次序,第一个块是 1,注意不是从 0 开始的。totalChunks
: 文件被分成块的总数。chunkSize
: 分块大小,根据totalSize
和这个值你就可以计算出总共的块数。注意最后一块的大小可能会比这个要大。currentChunkSize
: 当前块的大小,实际大小。totalSize
: 文件总大小。identifier
: 这个就是每个文件的唯一标示。filename
: 文件名。relativePath
: 文件夹上传的时候文件的相对路径属性。
后端可根据传递的信息自由处理;一般是一个文件表一个文件夹表做关联。
状态码
200
,201
,202
: 当前块上传成功,不需要重传。404
,415
.500
,501
: 当前块上传失败,会取消整个文件上传。- 其他状态码: 出错了,但是会自动重试上传。
配置项
由于是对原simple-upload.js做的封装,大多数的配置可以参考原生js文档,部分配置与原生有些许不同,请注意仔细查看相关参考文档。
target
:目标上传地址URL,默认值为 '/'。
chunkSize
:分片时按照该值来分。最后一个上传分片的大小是可能是大于等于1倍的这个值但是小于两倍的这个值大小
simultaneousUploads
:并发上传数,默认 3。
fileParameterName
:上传文件时文件的参数名,默认 file。
headers
:额外的一些请求头,例如有时我们需要在header中向后台传递token,默认为对象: {}。
maxChunkRetries
:最大自动失败重试上传次数,值可以是任意正整数,如果是 undefined 则代表无限次,默认 0。
chunkRetryInterval
:重试间隔,值可以是任意正整数,如果是 null 则代表立即重试,默认 null。
parseTimeRemaining(timeRemaining, parsedTimeRemaining) {Function}
:格式化剩余时间。以下代码把英文时间转成中文:
parseTimeRemaining: function (timeRemaining, parsedTimeRemaining) {
return parsedTimeRemaining
.replace(/\syears?/, '年')
.replace(/\days?/, '天')
.replace(/\shours?/, '小时')
.replace(/\sminutes?/, '分钟')
.replace(/\sseconds?/, '秒')
}
属性
autoStart {Boolean}
:默认 true, 是否选择文件后自动开始上传。
fileStatusText {Object}
:文件状态,文件在上传时会响应几种状态:
{
success: 'success',
error: 'error',
uploading: 'uploading',
paused: 'paused',
waiting: 'waiting',
}
事件
fileAdded(file)
:添加了一个文件事件,一般用做文件校验,比如要校验文件md5时,先触发该事件。 可以当作上传前的钩子,校验文件类型、大小或者数量限制等
fileSuccess(rootFile, file, message, chunk)
:一个文件上传成功事件,第一个参数 rootFile 就是成功上传的文件所属的根 Uploader.File 对象,它应该包含或者等于成功上传文件;第二个参数 file 就是当前成功的 Uploader.File 对象本身;第三个参数就是 message 就是服务端响应内容,永远都是字符串;第四个参数 chunk 就是 Uploader.Chunk 实例,它就是该文件的最后一个块实例,如果你想得到请求响应码的话,chunk.xhr.status 就是。
fileError(rootFile, file, message, chunk)
:上传出错。
fileProgress(rootFile, file, chunk)
:一个文件在上传中,监听文件上传进度。
fileRemoved(rootFile, file)
:从上传列表移除文件。
注意:所有的事件都会通过 lodash.kebabCase 做转换,例如 fileSuccess
就会变成 file-success
。
方法绑定的使用:
<uploader ref="uploader" class="avatar-uploader":options="options" :file-status-text="statusText" @file-added="onFileAdded" @file-success="onFileSuccess" @file-progress="onFileProgress" @file-error="onFileError" @file-removed="fileRemoved">
Uploader.File 获取实例
mounted () {
this.$nextTick(() => {
window.uploader = this.$refs.uploader.uploader
})
}
//实例的调用:
window.uploader.cancel()
.assignBrowse(domNodes, isDirectory, singleFile, attributes)
指定 DOM 元素可以选择上传。(用于实现自定义上传文件/文件夹按钮,由于使用的框架自带主题颜色更换,如果使用默认按钮无法与框架主题色兼容,所以获取dom后调用此实例方法使自定义的按钮也具备上传能力,下方拖拽区域同理)
domNodes
DOM 元素
isDirectory
如果传入的是 true
则代表是要选择文件夹上传的,你可以通过判断 supportDirectory
来决定是否设置
singleFile
是否只能选择单个文件
attributes
传入的其他属性值,例如你可以传入 accept
属性的值为 image/*
,这样就意味着点选的时候只能选择图片。
注意: 避免使用 a
或者 button
标签作为选择文件按钮。
.assignDrop(domNodes)
指定 DOM 元素作为拖拽上传目标。
.unAssignDrop(domNodes)
取消指定的 DOM 元素作为拖拽上传目标。
.getRoot()
获取当前文件所属的根文件,这个根文件就是包含在 uploader.fileList
中的.
.progress()
返回一个 0 到 1 的数字,代表当前上传进度。
.pause()
暂停上传文件。
.resume()
继续上传文件。
.cancel()
取消上传且从文件列表中移除。
.retry()
重新上传文件。
.bootstrap(
) 重新初始化 Uploader.File
对象的状态,包括重新分块,重新创建新的 XMLHttpRequest 实例。
.isUploading()
文件是否仍在上传中。
.isComplete()
文件是否已经上传完成。
.sizeUploaded()
已经上传大小。
.timeRemaining()
剩余时间,基于平均速度的,如果说平均速度为 0,那么值就是 Number.POSITIVE_INFINITY
。
.getExtension()
获取小写的后缀。
.getType()
获取文件类型。
开发遇到的问题
1、上传文件夹的大致原理本质上还是上传的文件,只是文件被带上了文件夹相关的路径,空文件夹是无法发起请求的,如需完成新建空文件夹的操作需要单独调用新建文件夹接口完成一个对文件夹表的新增操作。
2、当上传文件夹时,若文件夹包含子文件夹的情况,由于上传是异步的,有可能导致上传的文件夹结构异常或上传失败,需要做同步处理,前端有一个并发上传数的配置应该是前端的同步配置,但是存在部分问题待解决,时间原因,拜托后端对这个上传做了同步处理解决的。
3、并发上传数问题,默认给了3个,并发数量改为1就会变成同步上传,一个一个上传,按理前端的同步处理就是对这个参数做设置。但是在上传列表中不会结束已完成的上传任务,导致一直卡在第一个任务,我是自己手动去移除已完成的任务来解决的这个问题。这个问题自己根据业务调整吧。
4、默认的上传列表会随着上传文件的增多自动撑高,影响了页面的其他内容,做了一套显隐处理:存在上传任务时会出现一个上传中的图标,需要点击图标才会出现这个脱标的上传进度框,任务完成后自动清除文件列表,解除上传中状态。
1、参考文章1:使用vue-simple-uploader上传文件和文件夹 作者:月光光
2、参考文章2:simple-uploader.js 功能强大的上传组件
3、参考文档3:vue-simple-uploader组件的一些使用心得 作者:随遇而安丶
4、完整配置项请点此查看: simple-uploader.js github地址及参考文档