效果图

一、安装所需依赖包
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博客



















