yj-filepool
v3.0.10
Published
<br/>
Downloads
3
Readme
yj-filepool / 文件上传池
功能点
- ✔ v-model双绑
- ✔ 支持分片上传/断点续传
- ✔ 支持上传进度显示
- ✔ 支持格式限制/大小限制/数量限制 可针对不同类型分别设置
- ✔ 支持上传后预览/禁用时预览
- ✔ 全局安装/局部引入 通用参数仅需配置一次
- ✔ 支持自定义上传/自定义上传参数/自定义上传方法
- ✔ 自定插槽,展示和上传按钮支持通过插槽配置
安装
$ yarn add yj-filepool
// sliceFile, MB, GB 仅作为工具函数、常量 可选
import Filepool from 'yj-filepool'
// 组件内引入
components: { Filepool }
// 全局引入
Vue.use(Filepool, {})
使用
<Filepool v-model="" fileType="video"/>
属性
| 属性名 | 说明 | 配置方式 | 数据类型 | 可选值 | 默认值 | | --- | --- | --- | --- | --- | --- | | v-model | 文件链接 | props | string / array | | | | multiple | 是否上传多个文件 | props | boolean | | false | | originalName | 是否显示原始文件名称 | props | boolean | | false | | disabled | 是否禁用 | props | boolean | | false | | fileTypeCatalog | 文件目录,仅支持全局配置 | global | object | | see below | | fileType | 指定使用fileTypeCatalog中的哪一个 | props | string, array | prop of fileTypeCatalog | | | maxSize | 大小限制 单位MB | props | number | | 200 | | count | 数量限制, multiple模式时有效 | props | number | | 1 | | delConfirmation | 是否在删除文件时弹框确认 | global, props | boolean | | false | | placeholder | 提示信息(hint) | global, props | string | | '点击上传' | | localMode | 本地模式,开启本地模式文件将不会自动上传,直接返回整个文件原始信息 | props | boolean | | false |
插槽(slot)
| 名称 | 参数 | 说明 | | --- | --- | --- | | default | | 默认插槽,覆盖默认上传文件区域 | | fileList | fileList | 文件列表插槽,传入此插槽可完全自定义文件列表展示区域 |
函数
| 名称 | 参数 | 说明 | | --- | --- | --- | | filesChange | fileList | 文件传后的回调,字段见下表 |
interface File {
// 文件名称
fileName?: string;
// 文件对象
file?: any;
// 上传进度
progress?: number;
// 0 上传中 1 失败 2上传成功 3已关闭
status?: number;
// 文件访问路径
url?: string;
// 文件类型
type?: string;
// 文件类型
size?: string | number;
// 文件类型
loading?: boolean;
}
接口相关
由于分片上传的实现由后端主导 五花八门 无法统一 故上传的整个过程放开自定义
| Attribute | Description | Configuration Mode | Type | Accepted Values | Default | | --- | --- | --- | --- | --- | --- | | upload | 自定义上传的整个过程 | global, props | function | see below | |
upload
import Filepool from 'filepool'
import request from '@/utils/request' // 你的axios封装
Vue.use(Filepool, {
upload ({ file, jsonToFormData, }) {
return new Promise((resolve, reject) => {
request({
url: '',
method: 'POST',
data: jsonToFormData({
file,
}),
}).then(res => {
if (typeof res?.data === 'string') {
resolve(res.data)
} else {
reject(res.message)
}
}).catch(e => {
reject(e)
})
})
},
})
相对完整的分片上传示例
含中途取消、进度显示、断点续传等
import Filepool from 'filepool'
import request from '@/utils/request' // 你的axios封装
import { CancelToken } from 'axios'
let cancelUpload, failTimes = 0, retryTimes = 3
Vue.use(Filepool, {
/**
* @return {promise}
*/
upload ({
file, // 用户选择的二进制文件
fileType, // 当前实例的文件类型
/**
* json转FormData
*
* @param {json} param - 参数
* @return {formData} formData格式的参数
*/
jsonToFormData,
/**
* 设置上传进度
*
* @param {number} progress - 进度 范围[0, 1]
*/
setProgress,
/**
* 切割文件(分片上传时有用)
*
* @param {file} file - 二进制文件
* @param {number} chunkSize - 分片大小 单位字节 默认10M
* @return {array} 文件分片
*/
sliceFile,
MB, GB, // 文件容量单位 方便用于chunkSize参数
}) {
const chunkSize = 10 * MB
setProgress(0)
failTimes = 0
cancelUpload = null
let chunks = sliceFile(file, chunkSize), count = 0
const formData = jsonToFormData({
domainId: 4,
dir: fileType,
chunkTotal: chunks.length.toString(),
fileName: file.name,
})
return new Promise((resolve, reject) => {
function recursion () {
formData.set('file', chunks[count])
formData.set('chunk', count.toString())
request({
baseURL: '',
url: '',
method: 'POST',
data: formData,
timeout: 0,
onUploadProgress (progressEvent) {
if (progressEvent.lengthComputable) {
const pct = (chunkSize * count + progressEvent.loaded) / file.size
setProgress(pct >= 1 ? .99 : pct)
}
},
cancelToken: new CancelToken(function executor (c) {
// executor 函数接收一个 cancel 函数作为参数
cancelUpload = c
}),
}).then(res => {
let data = 'data' in res ? res.data : res
if (data?.status === '200') {
setProgress(1)
resolve(data.url)
} else if (count++ < chunks.length - 1) {
formData.set('taskId', data.url)
recursion()
} else {
setProgress(1)
reject('上传失败')
}
}).catch(e => {
// 断点续传
if (failTimes++ < retryTimes) {
recursion()
} else {
reject('上传失败')
}
})
}
recursion()
})
}
})
文件形态
- 服务器模式:配置了upload时进入该模式
文件目录
你可以全局定义一个文件目录 预设一些你可能用到的文件类型(任何类型都可以) 并规定这些类型的格式和大小 在组件中使用fileType属性来对应
默认值
fileTypeCatalog: {
image: {
maxSize: 10,
accept: '.jpg,.jpeg,.png',
},
video: {
maxSize: 200,
accept: '.mp4',
},
audio: {
maxSize: 60,
accept: '.mp3',
},
apk: {
maxSize: 200,
accept: '.apk',
},
excel: {
maxSize: 100,
accept: '.xlsx,.xls',
},
}
例子
<template>
<Filepool fileType="abc"/>
</template>
<script>
import Filepool from 'filepool'
Vue.use(Filepool, {
fileTypeCatalog: {
abc: {
maxSize: 10,
accept: '.abc',
},
}
})
</script>
获取文件上传原始信息
监听事件 filesChange
即可
Notice
全局配置被props中的同名参数覆盖 对象会进行混入
maxSize权重排序:props > fileTypeCatalog中对应的maxSize > 全局默认的maxSize
如果仅上传图片 请使用yj-imgpond(附带图片编辑功能)