前端vue切片上传,公司项目需求,该项目用的是 Ant Design Vue 3组件库,别的组件库其核心原理也一样,有需要的小伙伴自取。
<template>
<a-upload v-model:fileList="fileList" :remove="handleRemove" :before-
upload="beforeUpload" accept=".jpg,.png," :maxCount=1>
<div class="uploadName">上传</div>
</a-upload>
</template>
js部分:
<script setup>
import { ref, reactive } from "vue";
import md5 from 'spark-md5';//引入md5
const fileList = ref([]);
const formState = reactive({
md5: null,
});
const beforeUpload = option => {
let file = option.file;
let types = ['image/png', 'image/jpg'];
const isImage = types.includes(file.type);
let isLt100M = file.size / 1024 / 1024 <= 1024;//文件大小不能超过1GB;
if (!isImage) {
message.error('文件类型错误');
return false;
} else if (!isLt100M) {
message.error('文件大小超过限制');
return;
}
// 1.获取md5的值
const { size, type, name, lastModified } = file;
const strfile = name + size + type + lastModified;
console.log(strfile);
// const result = fileParse(strfile, 'buffer')// fileParse转换函数附在最下面👇,将file转成buffer格式数据,//根据项目需求是否需要
const spark = new md5()
spark.append(strfile)
const hash = spark.end() // 获取到的文件md5值
formState.md5 = hash;
// 2.切片
const partSize = 3 * 1024 * 1024 // 考虑到前后端上传效率,我这里是切成3M/片,这个可根据项目实际需要自己决定
const share = file.size <= partSize ? 1 : Math.ceil(file.size / partSize);//切片数
let cur = 0;
const partList = [] // 存储文件切片的数组
for (let i = 0; i < share; i++) {
const obj = {
file: file.slice(cur, cur + partSize), // 调用file.slice方法进行file的切片,第一个参数从哪里开始切,第二个参数切到哪里
// id: i// 每一个切片的单独标示,后期续传时用与去除已上传部分的切片
}
partList.push(obj) // 把切的每一片统一放到一个数组里
cur += partSize;
}
//console.log(partList, share, fileName, cur);
newRequestArr(partList, share, fileName, cur,)
};
//3.开始切片
const newRequestArr = (partList, share, fileName) => {
console.log(partList, share, fileName, '开始切片');
// let chunkTotal = share;
let i = 0
const fn = () => {
let userId = localStorage.getItem('userId');//用户id
let nowTime = parseInt(new Date().getTime() / 1000) + '';
let guid = userId + nowTime;//唯一文件标识,用户id+当前时间戳
const formData = new FormData() // 通过form将file切片传给后台
formData.append('file', partList[i].file);//当前文件
formData.append('chunk', Number(i + 1));//当前分片符号
formData.append('chunkTotal ', share);//总切片数
formData.append('guid', guid);
shardUpload(formData).then((res => {
i += 1
if (i < partList.length) {
if (res.code == 0) {
fn();
}
} else {
complete(share, guid, fileName) // 如果是最后一个切片,则调用合并函数
}
}))
}
fn();
};
// 4.文件合并
const complete = (chunkTotal, guid, name) => {
//调取后端提供的合并接口,参数与后端约定好
shardMerge({
chunkTotal: chunkTotal,
guid: guid,
name: name,
}).then((res) => {
if (res.code === 0) {
message.success('上传成功')
}
})
}
</script>
以上是完整代码,可能有个别参数与大家的项目需求有出入,可根据自身需要进行相应的调整。
完结,撒花...