利用Vue3+Element-plus實現(xiàn)大文件分片上傳組件
一、背景
實際項目中遇到需要上傳幾十個G的3d模型文件,傳統(tǒng)上傳就不適用了。
結(jié)合element提供的上傳組件自己封裝了文件分片上傳的組件。
思路:
- 把文件拆分成若干分片
- 依次上傳分片(每次上傳前可校驗該分片是否已經(jīng)上傳)
- 發(fā)起合并分片的請求
二、技術(shù)棧
Vue3+Ts+Element-Plus
其他庫:spark-md5
后端接口:
- 上傳分片接口
- 校驗分片是否已上傳接口
- 合并分片接口
三、核心代碼實現(xiàn)
Element組件基礎(chǔ)配置
<el-upload drag :file-list="fileList" :on-change="onUpload" :auto-upload="false" ref="uploadfile" :limit="1" :show-file-list="false" ></el-upload>
這里有個點:必須要定義file-list屬性,不然clearFiles等官方外部方法沒有效果
核心方法就是onUpload
const onUpload = async (File:any) => {
const chunkSize = 30 * 1024 * 1024; // 分片大小
const file = File.raw // 文件
const fileSize = File.size // 文件大小
let chunkCount = Math.ceil(fileSize / chunkSize) // 分片數(shù)量
if(chunkSize > fileSize){ // 文件過小就一片
chunkCount = 1
}
// 文件md5,給文件一個唯一標識
const fileMd5 = await getFileMd5(file, chunkCount, chunkSize);
// 上傳分片
for( let i=0;i<chunkCount;i++) {
const start = i * chunkSize //分片開始
const end = Math.min(fileSize, start + chunkSize) // 分片結(jié)束
const _chunkFile = File.raw.slice(start, end) // 分片文件
// 定義分片上傳接口參數(shù),跟后端商定
const formdata = new FormData()
formdata.append('chunkNumber', i.toString())
formdata.append('chunkSize', _chunkFile.size)
formdata.append('file', _chunkFile)
formdata.append('fileName', File.name)
formdata.append('fileSign', fileMd5)
formdata.append('totalChunks', chunkCount.toString())
formdata.append('totalChunkSize', fileSize)
// 檢查分片文件是否上傳-沒有上傳則上傳
const params = { chunkNumber: i, fileSign: fileMd5 }
const { data } = await checkChunkFile(params) // 檢驗接口-自己定義
if(!data.flag){
console.log("開始上傳第" + i + "個分片")
await uploadChunkFile(formdata) // 上傳接口-自己定義
}
}
// 合并
const mergeData = { // 合并參數(shù)
fileName: File.name,
fileSign: fileMd5,
...
}
mergeFile(mergeData)// 合并接口-自己定義
}
getFileMd5方法生成文件md5
const getFileMd5 = (file: File, chunkCount: number, chunkSize: number) => {
return new Promise((resolve, reject) => {
const blobSlice = File.prototype.slice
const chunks = chunkCount
let currentChunk = 0
const spark = new SparkMD5.ArrayBuffer()
const fileReader = new FileReader()
fileReader.onload = e => {
spark.append(e.target?.result)
currentChunk ++
if(currentChunk < chunks){
loadNext()
} else {
const md5 = spark.end()
resolve(md5)
}
}
fileReader.onerror = e => {
reject(e)
}
function loadNext () {
const start = currentChunk * chunkSize
let end = start + chunkSize
if(end > file.size){
end = file.size
}
fileReader.readAsArrayBuffer(blobSlice.call(file, start, end))
}
loadNext()
})
}
getFileMd5 方法是同步任務(wù),文件過大會等待很久,可對頁面進行優(yōu)化處理,不然會造成卡著沒進行請求的錯覺。
四、總結(jié)
至于其他進度條、組件參數(shù)等代碼忽略掉了,可根據(jù)實際情況設(shè)計。
上面的核心代碼很多內(nèi)容是還可以拆分的,優(yōu)化空間很大。
該組件是一個一個分片的上傳,去掉await 就可以測試多個文件上傳。
到此這篇關(guān)于利用Vue3+Element-plus實現(xiàn)大文件分片上傳組件的文章就介紹到這了,更多相關(guān)Vue3 Element-plus大文件分片上傳組件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
electron-vite新一代electron開發(fā)構(gòu)建工具
這篇文章主要介紹了electron-vite新一代electron開發(fā)構(gòu)建工具,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-04-04
elementUI表格多選框this.$refs.xxx.toggleRowSelection無效問題
這篇文章主要介紹了elementUI表格多選框this.$refs.xxx.toggleRowSelection無效問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-11-11
利用Vue Router實現(xiàn)單頁面應(yīng)用(SPA)的代碼示例
在當今前端開發(fā)中,單頁面應(yīng)用(SPA)已成為一種主流的開發(fā)模式,它通過在用戶與網(wǎng)頁之間提供更流暢的交互體驗,來改變傳統(tǒng)多頁面應(yīng)用的思維,本文將詳細介紹如何利用 Vue.js 中的 Vue Router 來實現(xiàn)一個簡單的單頁面應(yīng)用,需要的朋友可以參考下2025-01-01
Vue使用vue-draggable 插件在不同列表之間拖拽功能
這篇文章主要介紹了使用vue-draggable 插件在不同列表之間拖拽,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-03-03
Vue使用ExcelJS實現(xiàn)專業(yè)級Excel導出解決方案
ExcelJS 是 Node.js 和瀏覽器環(huán)境中功能最全面的 Excel 處理庫之一,就像一個專業(yè)的 Excel 工作站,下面小編就為大家詳細介紹一下如何使用ExcelJS實現(xiàn)專業(yè)級Excel導出吧2025-07-07
說說如何在Vue.js中實現(xiàn)數(shù)字輸入組件的方法
這篇文章主要介紹了說說如何在Vue.js中實現(xiàn)數(shù)字輸入組件的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-01-01
Vue編譯器源碼分析compileToFunctions作用詳解
這篇文章主要為大家介紹了Vue編譯器源碼分析compileToFunctions作用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-07-07
vuex 第三方包實現(xiàn)數(shù)據(jù)持久化的方法
本文主要介紹了vuex 第三方包實現(xiàn)數(shù)據(jù)持久化的方法,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-09-09

