vue3 前端大文件分片上传
vue
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
项目地址:https://gitcode.com/gh_mirrors/vu/vue
免费下载资源
·
1、大文件上传直接传的弊端?
大文件上传,当大文件上传时耗费时间长,有被中断的可能性,当被中断后,无论前面上传进度是多少,都会归0,无法实现断点续传
2、分片上传的好处?
分片上传:分片上传就是把要上传的大文件,按照某个大小进行切片,把切片文件逐一上传,在这里需要后端的配合,给前端分片上传和上传完合并的接口
3、分片上传原理?
分片上传把大文件变成了一个个的小文件上传,可以提升速度,如果中途中断,和后端配合设好唯一标识,下次上传同一个文件时根据文件本身的信息,例如文件名、文件大小等进行判断,如果新上传的文件和之前上传中断的文件是同一个文件时,可以从上传中断的分片继续上传,节约时间,从而实现断点续传
4、前端需要做的部分?
前端所需要做的工作是把文件进行分片,把分片逐一上传,并在最后一个切片上传完毕后请求后端进行文件合并
5、何时开始分片?
当选择完文件,拿到文件信息,就可以进行分片了
6、具体实现
html内容:
<div class="uploader">
<ul class="list">
<li class="list__item" v-for="(item, index) in fileList" :key="item.url">
<span>
<i class="icon-icon-" />
<span
class="list__item-name"
:title="item.name"
>{{ interceptStr(item.name) }}
</span>
</span>
<i class="icon-guanbi" @click="cancel({ item, index })" />
</li>
</ul>
<p class="uploader__upload">
<i class="icon-jiahao" /> 上传文件
<input
:accept=""
type="file"
class="uploader__input"
@click="clearValue"
@change="selectFile"
/>
</p>
</div>
js内容:
//创建一个文件对象
let files = {}
//文件上传列表数据
let fileArray=''
//当前上传坐标
let pareIndex = 0
//请求接口所需参数
let tempFile=''
let tempFile=''
let tempObject=''
let id=''
let modelUuid=''
//上传文件列表
const fileList = computed(() => {
return Array.isArray(fileArray)
? fileArray
: !fileArray
? []
: [fileArray]
})
//清空input的value
const clearValue = e => {
e.target.value = ''
}
const selectFile = e =>{
//获取所选文件信息
files = e.target.files[0]
//形成文件列表
const { name } = files
fileArray={name }
//请求文件分片
uploadFileSilce(files, pareIndex)
}
//请求合并文件
const mergeFile=(pareTotal)=>{
let params={
folderName:tempFile,
objectName:tempObject,
partNum:pareTotal,
stationModelId:id
}
//请求后端合并接口
modelServe.mergeUpload(params).then(res => {})
}
//文件切片
const uploadFileSilce = (file, pareIndex) => {
// 文件名
const { name } = file;
//文件分片后,每一个分片的名字,按照坐标逐一递增
let portFileName=file.name.substring(0,file.name.lastIndexOf("."))+'_'+`${pareIndex+1}`+file.name.substring(file.name.lastIndexOf("."))
// 文件大小
const { size } = file;
// 分片大小(50M,可以自行设置)
const pareSize = 1024 * 1024 * 50;
// 分片总数
const pareTotal = Math.ceil(size / pareSize);
// 如果 当前分片索引 大于 总分片数
if (pareIndex >= pareTotal) {
// 合并文件
mergeFile(pareTotal);
return;
}
// 文件开始结束的位置
const start = pareIndex * pareSize;
const end = Math.min(start + pareSize, size);
// 开始切割
const packet = new File([file.slice(start, end)], portFileName)
// 拼接请求参数
const formData = new FormData();
formData.append('files', packet);
formData.append('partFileIndex', pareIndex+1)//当前分片下标
formData.append('partFileSum', pareTotal)//总分片数
formData.append('uuid', modelUuid)//文件uuid,(这里是跟后端获取的,根据自己需求修改)
formData.append('filesName', portFileName)//分片文件名称
formData.append('stationModelId', id)//id
formData.append('fileSize', file.size)//大小这里是跟后端获取的,根据自己需求修改)
// 如果 当前分片索引 小于 总分片数
if (pareIndex < pareTotal) {
//请求后端分片接口
modelServe.portUpload(formData).then(res => {
const { code, msg, data } = res.data
if (code === 0) {
pareIndex++;
//准备合并所需要的参数
tempFile=res.data.data.folderName
tempObject=res.data.data.objectName
// 递归调用 分片函数
uploadFileSilce(file, pareIndex);
}
})
}
};
css内容:
.uploader {
width: 100%;
&__upload {
// background: #f2f3f5;
// border-radius: 2px;
border: 1px solid #e5e6eb;
height: 0.161rem;
min-height: 25px;
width: 100%;
position: relative;
text-align: center;
line-height: 0.161rem;
color: #fff;
width: 104px;
height: 32px;
background: #3491FA;
border-radius:4px;
opacity: 1;
> input {
position: absolute;
opacity: 0;
left: 0;
right: 0;
height: 100%;
font-size: 0;
cursor: pointer;
}
}
&__input{
color: #fff;
width: 104px;
height: 32px;
background: #3491FA;
border-radius: 4px 4px 4px 4px;
opacity: 1;
}
}
.list {
display: flex;
flex-direction: column;
&__item {
background: #e6effe;
border-radius: 2px;
height: 0.161rem;
min-height: 25px;
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
font-family: SourceHanSansCN-Regular, SourceHanSansCN;
font-weight: 400;
color: #165dff;
margin-bottom: 10px;
white-space: nowrap;
padding: 0 0.056rem;
&-name {
margin-left: 0.056rem;
cursor: pointer;
}
}
.icon-guanbi {
cursor: pointer;
}
}
感谢BreenCL博主的分享,感谢其他伙伴分享的大文件分片文章,学习到了许多,都写的很详细,如果大家有需要可以移步查看。
GitHub 加速计划 / vu / vue
207.54 K
33.66 K
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:2 个月前 )
73486cb5
* chore: fix link broken
Signed-off-by: snoppy <michaleli@foxmail.com>
* Update packages/template-compiler/README.md [skip ci]
---------
Signed-off-by: snoppy <michaleli@foxmail.com>
Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 4 个月前
e428d891
Updated Browser Compatibility reference. The previous currently returns HTTP 404. 5 个月前
更多推荐
已为社区贡献12条内容
所有评论(0)