Vue之大文件分片上传
记录一次项目中用到的大文件分片上传vue解决实例如下
首先是封装的请求方法(文件...Sentlas.js
部分内容)如下:
这里加了上传进度展示,请求包和数据包主体展示,所以传入了回调及vue实体
import axios from 'axios'
const Sentlas = {
// ...放置了axios方法和具体的请求方法
uploadFragmentResourceFile: function(data) {
this.beforeRequest()
return this.request({
url: '...',
params: { token: this.Token },
method: 'post',
data
})
},
}
/**
* 上传资源文件(分片)
* @param {File} file
* @param {String|null} fileName
* @param {Function|null} callback
* @param {Object} vm
* @returns
*/
export function uploadFragmentResourceFile(file, fileName = null, callback = null, vm = null) {
if (file instanceof File) {
if (fileName == null) {
fileName = file.name // 文件名
}
var size = file.size // 文件大小
var shardSize = 1024 * 1024 * 4 // 分片大小,这里设置4M
var shardCount = Math.ceil(size / shardSize) // 分片数量
var slice = function(f, inx) {
// 容错
if (inx >= shardCount) return
// 计算偏移量
var start = inx * shardSize
var end = start + shardSize
// 文件进行切片
var packet = f.slice(start, end)
var formData = new FormData()
formData.append('file', packet, fileName)
formData.append('fileName', fileName)
formData.append('subId', inx)
formData.append('total', shardCount)
return Sentlas.uploadFragmentResourceFile(formData).then(r => {
if (r.code === 20010) {
// 继续上传
if (typeof callback === 'function') {
callback(vm, inx, shardCount, formData, r)
}
return slice(file, inx + 1)
} else if (r.code === 20000) {
// 成功
if (typeof callback === 'function') {
callback(vm, inx, shardCount, formData, r)
}
return Promise.resolve(r)
} else {
// 有错误
console.log(r.msg)
return slice(file, inx)
}
})
}
return slice(file, 0)
} else {
console.log('不是标准文件对象.')
return Promise.resolve('不是标准文件对象.')
}
}
vue文件:
<template slot="title">
<div>
<b>上传资源文件(分片)</b>
<div>
<el-form ref="api3form" :model="api3Data" size="mini" label-width="auto">
<el-form-item label="选择文件">
<input ref="clearFile3" type="file" @change="getFile3($event)">
</el-form-item>
<div>
<el-progress
:text-inside="true"
:stroke-width="18"
:percentage="f3progress"
/>
</div>
</el-form>
</div>
<div style="padding: 1em">
<el-button
size="mini"
type="primary"
round
@click="api3()"
>发送请求</el-button>
</div>
</div>
</template>
<script>
import { uploadFragmentResourceFile } from '@/utils/Sentlas'
export default {
data() {
return {
files3: [],
f3progress: 0,
api3Data: {}
}
},
methods: {
api3: function() {
if (this.files3.length !== 1) {
this.$message('请先选择文件')
return false
}
if (this.recvClean) this.cleanMessage()
var file = this.files3[0]
var fileName = file.name
this.writeNews(
1,
this.api3Data,
'上传资源文件(分片): POST /cgi-bin/upload-fragment-resource-file?token=...'
)
var vm = this
uploadFragmentResourceFile(
file,
fileName,
function(vmer, inx, total, request, response) {
vmer.f3progress = Math.round((100 * (inx + 1)) / total)
var object = {}
request.forEach(function(value, key) {
if (value instanceof File) {
object[key] = '文件二进制数据...'
} else {
object[key] = value
}
})
vmer.writeNews(1, object)
vmer.writeNews(0, response)
},
vm
)
}
}
}
</script>
上边仅贴出了部分代码,
由于时间仓促,错误与疏忽之处在所难免,希望各位朋友们以邮件的形式反馈问题给我,再次表示感谢!
- 作者:xmlwch
- 原文链接:https://blog.xmlwch.cn/2021/08/20/html/fragment_upload.html
- 版权声明:本作品采用 知识共享 署名-相同方式共享 4.0 国际(CC BY-SA 4.0)许可协议 进行许可,转载无需与我联系,但请注明出处。