vue3+antdv实现大文件上传优化
一、相关配置下载
选择一种方式下载,npm/yarn都可以
npm i mockjs
npm i axios
二、mock配置
1.创建文件夹src/mock/index.js
2.在main.js
中引入
import './mock/index'
3.在mock/index.js中引入
//引入mock模块
import Mock from "mockjs";
// 模拟图片上传接口
Mock.mock('/api/upload', 'post', (options) => {
// 解析请求参数
const formData = options.body;
// 模拟上传操作
// 模拟返回上传成功的响应
return Mock.mock({
code: 200,
message: '上传成功',
data: {
url: '@image',
},
});
});
// 设置拦截Ajax请求,生成模拟数据
Mock.setup({
timeout: '1000', // 设置响应时间范围
});
4.前端代码实现
<template>
<a-upload :before-upload="beforeUploadOld" :custom-request="customRequestOld" :show-upload-list="false"
:multiple="true">
<a-button icon="upload">
上传
</a-button>
</a-upload>
<a-upload :before-upload="beforeUpload" :custom-request="customRequest" :show-upload-list="false" :multiple="true">
<a-button icon="upload">
上传优化
</a-button>
</a-upload>
</template>
<script setup>
import axios from 'axios';
import { message } from 'ant-design-vue';
const beforeUpload = (file) => {
// 在上传之前的操作,例如限制文件大小、类型等
console.log('before upload:', file);
return true;
}
const beforeUploadOld = (file) => {
// 在上传之前的操作,例如限制文件大小、类型等
console.log('before uploadold:', file);
return true;
}
const customRequestOld = async (options) => {
const formData = new FormData()
formData.append('file', options.file)
let startTime = performance.now();
await axios
.post('/api/upload', formData)
.then((response) => {
console.log('Upload success:', response.data);
message.success('上传成功');
// 处理上传成功的操作
})
.catch((error) => {
console.error('Upload error:', error);
message.error('上传失败');
// 处理上传错误的操作
});
let endTime = performance.now();
let uploadTime = (endTime - startTime); // 转换为秒
console.log("优化前上传所需时间", uploadTime);
}
const customRequest = async (options) => {
const file = options.file
let startTime = performance.now();
const chunkSize = 1000000 // 每个分片的大小(字节)
const totalChunks = Math.ceil(file.size / chunkSize)
const chunkRequests = []
for (let i = 0; i < totalChunks; i++) {
const start = i * chunkSize
const end = start + chunkSize
const chunk = file.slice(start, end)
const formData = new FormData()
formData.append('file', chunk)
formData.append('chunkIndex', i)
formData.append('totalChunks', totalChunks)
const chunkRequest = axios.post('/api/upload', formData)
chunkRequests.push(chunkRequest)
}
axios.all(chunkRequests).then(() => {
message.success('上传成功');
}).catch(() => {
message.error('上传失败');
})
let endTime = performance.now();
let uploadTime = (endTime - startTime); // 转换为秒
console.log("优化后上传所需时间", uploadTime);
}
</script>
<style scoped lang='less'></style>
customRequest
方法接收一个options
对象参数,其中包含了file
属性,表示需要上传的文件。代码首先定义了每个分片的大小chunkSize
,然后计算了需要的总分数totalChunks
。
接下来使用一个循环来迭代生成每个分片的请求。在每次循环中,我们根据chunkSize
和循环索引计算出当前分片的起始和结束位置,并使用file.slice
方法切割出当前分片。然后,我们创建一个FormData
对象,并通过append
方法将file
、chunkIndex
和totalChunks
添加到表单中。
接下来,我们使用axios.post
方法发送分片上传的请求,并将返回的请求对象存储在chunkRequests
数组中。
最后,我们使用axios.all
方法将所有的分片上传请求一起发送,并通过.then
方法注册一个回调函数,在所有分片上传完成后执行。