效果图
一、安装所需依赖包
npm install vue-simple-uploader@next --save
npm install spark-md5 --save
二、main.ts 注册组件
import { createApp } from 'vue'
import uploader from 'vue-simple-uploader'
import 'vue-simple-uploader/dist/style.css'
import App from './App.vue'
const app = createApp(App)
app.use(uploader)
app.mount('#app')
三、创建uploader组件UploadChunk.vue
<template>
<uploader
ref="uploaderRef"
:options="options"
:autoStart="false"
:file-status-text="fileStatusText"
class="uploader-ui"
@file-added="onFileAdded"
@file-success="onFileSuccess"
@file-progress="onFileProgress"
@file-error="onFileError"
>
<uploader-unsupport></uploader-unsupport>
<uploader-drop>
<div>
<uploader-btn :attrs="attrs">选择文件</uploader-btn>
</div>
</uploader-drop>
<uploader-list></uploader-list>
</uploader>
</template>
<script setup lang="ts">
import { reactive, ref } from 'vue';
import SparkMD5 from 'spark-md5';
import { ElMessage } from 'element-plus';
import { mergeFile } from '@/api/configuration/localTask'
// 记录是否上传过文件
const isUpload = ref(false)
const options = reactive({
target: `http://xxxxx`, // 目标上传 URL
// 额外的自定义查询参数
query: {},
// query: (file: any, chunk: any) => {
// return {
// ...file.params,
// }
// },
headers: {}, // 自定义头部信息
chunkSize: 10240000, // 分块大小
fileParameterName: 'upfile', // 上传文件时文件的参数名,默认file
maxChunkRetries: 3, // 最大自动失败重试上传次数
testChunks: true, // 是否开启服务器分片校验
// 服务器分片校验函数
checkChunkUploadedByResponse: function (chunk: any, response_msg: any) {
let objMessage = JSON.parse(response_msg);
if (objMessage.skipUpload) {
return true;
}
return (objMessage.uploadedChunks || []).indexOf(chunk.offset + 1) >= 0;
},
});
const attrs = reactive({
accept: ['.xml']
});
const fileStatusText = reactive({
success: '上传成功',
error: '上传失败',
uploading: '上传中',
paused: '暂停',
waiting: '等待上传',
});
const onFileAdded = (file: any) => {
computeMD5(file);
}
const onFileSuccess = (rootFile: any, file: any, response: any, chunk: any) => {
// 设置上传参数
file.refProjectId = 'sxx-file';
file.filename = file.name
file.identifier = file.uniqueIdentifier
mergeFile(file).then((res: any) => {
ElMessage.success('上传成功!')
isUpload.value = true
}).catch((error) => {
console.log(error)
});
}
const onFileError = (rootFile: any, file: any, response: any, chunk: any) => {
ElMessage({
type: 'error',
message: `上传失败!`
})
}
// 计算md5值
function computeMD5(file: any) {
file.pause();
//单个文件的大小限制2G
let fileSizeLimit = 2 * 1024 * 1024 * 1024;
if (file.size > fileSizeLimit) {
file.cancel();
}
let fileReader = new FileReader();
let blobSlice = File.prototype.slice;
let currentChunk = 0;
const chunkSize = 10 * 1024 * 1000;
let spark = new SparkMD5.ArrayBuffer();
let chunkNumberMD5 = 1;
loadNext();
fileReader.onload = (e: any) => {
spark.append(e.target.result);
if (currentChunk < chunkNumberMD5) {
loadNext();
} else {
let md5 = spark.end();
file.uniqueIdentifier = md5;
file.resume();
}
};
fileReader.onerror = function () {
ElMessage({
type: 'error',
message: `文件读取错误!`
})
file.cancel();
};
function loadNext() {
let start = currentChunk * chunkSize;
let end = start + chunkSize >= file.size ? file.size : start + chunkSize;
fileReader.readAsArrayBuffer(blobSlice.call(file.file, start, end));
currentChunk++;
}
}
</script>
<style scoped lang="scss">
.justify-content-center {
width: 100%;
display: flex;
justify-content: center;
}
.uploader-ui {
padding: 15px;
margin: 40px auto 0;
font-size: 12px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.4);
.uploader-btn {
margin-right: 4px;
font-size: 12px;
border-radius: 3px;
color: #fff;
background-color: #409eff;
border-color: #409eff;
display: inline-block;
line-height: 1;
white-space: nowrap;
}
.uploader-list {
max-height: 440px;
overflow: auto;
overflow-x: hidden;
overflow-y: auto;
}
}
</style>
四、组件使用
<template>
<div>
<upload-chunk />
</div>
</template>
<script setup lang="ts">
import UploadChunk from './UploadChunk.vue';
</script>
五、后台java相关代码
vue+springboot实现大文件上传-CSDN博客