vue3写法
<template>
<div>
<input type="file" @change="handleChange">
</div>
</template>
<script setup>
const uploadChunkList = []
const uploadFile = ''
const handleChange = (e) => {
let uploadFile = e.target.files[0]
console.log(uploadFile)
if (!uploadFile) return
// 转为二进制流
const chunkList = createChunk(uploadFile)
console.log('chunkList', chunkList)
uploadChunkList = chunkList.map(({ file }, index) => {
return {
file,
size: file.size,
percent: 0,
chunkName: `${uploadFile.name}-${index}`,
fileName: uploadFile.name,
index
}
})
console.log('uploadChunkList', uploadChunkList)
//转为表单格式的数据流
const formateList = uploadChunkList.map(({ file, fileName, index, chunkName }) => {
// 对象需要转成二进制数据流进行传输
const formData = new FormData() // 创建表单格式的数据流
// 将切片转换成了表单的数据流
formData.append('file', file)
formData.append('fileName', fileName)
formData.append('chunkName', chunkName)
return { formData, index }
})
console.log('formateList', formateList)
uploadChunks(formateList)
}
//切片
const createChunk = (file, size = 1 * 1024 * 1024) => {
const chunkList = []
let cur = 0
while (cur < file.size) {
chunkList.push({ file: file.slice(cur, cur + size) })
cur += size
}
return chunkList
}
//发接口请求上传切片
const uploadChunks = (formateList) => {
const requestList = formateList.map(({ formData, index }) => {
return requestUpload({
url: 'http://localhost:3000/upload', //接口地址
data: formData,
onUploadProgress: createProgress(uploadChunkList[index]) // 进度条函数拿出来写
})
})
// 合并切片请求
Promise.all(requestList).then(mergeChunks())
}
// 合并切片
const mergeChunks = () => {
requestUpload({
url: 'http://localhost:3000/merge',
data: JSON.stringify({
fileName: uploadFile.name,
size: 1 * 1024 * 1024
})
})
}
// 上传的进度
const createProgress = (item) => {
return (e) => {
// 为何函数需要return出来,因为axios的onUploadProgress就是个函数体
// 并且这个函数体参数e就是进度
item.percent = parseInt(String(e.loaded / e.total) * 100) // axios提供的
}
}
// 为了实现进度条,封装请求
const requestUpload = ({ url, method = 'post', data, headers = {}, onUploadProgress = (e) => e }) => {
return new Promise((resolve, reject) => {
// axios支持在请求中传入一个回调onUploadProgress,其目的就是为了知道请求的进度
axios[method](url, data, { headers, onUploadProgress })
.then(res => {
resolve(res)
})
.catch(err => {
reject(err)
})
})
}
onMounted(() => {
})
</script>
<style lang="scss" scoped>
.main-box {
font-size: 32px;
}
</style>