基于Vue 和 iView分片上傳功能實(shí)現(xiàn)(上傳組件)
在實(shí)際開發(fā)中,上傳大文件往往會面臨一些問題,如上傳速度慢、超時、網(wǎng)絡(luò)中斷等。為了更好地解決這些問題,我們可以使用分片上傳技術(shù)。分片上傳就是將文件拆分成多個小塊進(jìn)行上傳,每個小塊稱為“分片”,上傳成功后,服務(wù)器會將這些分片重新合并成完整的文件。
本文將通過一個基于 Vue 和 iView 的分片上傳示例,詳細(xì)介紹如何實(shí)現(xiàn)文件分片上傳,并且為每個上傳的分片提供上傳進(jìn)度顯示和錯誤處理。
使用分片上傳技術(shù)的優(yōu)勢:
- 提高上傳成功率:即使某個分片上傳失敗,只需要重新上傳該分片,其他分片不受影響。
- 支持?jǐn)帱c(diǎn)續(xù)傳:分片上傳可以幫助我們實(shí)現(xiàn)斷點(diǎn)續(xù)傳功能。
- 支持上傳大文件:通過將大文件切分成小的分片,避免一次性上傳造成的超時問題。
前提條件
- Vue.js:用于構(gòu)建用戶界面。
- iView:一款基于 Vue 的 UI 組件庫,其中包括用于文件上傳的
Upload
組件。 - Axios:用于發(fā)起 HTTP 請求,進(jìn)行文件上傳。
- 后端 API:需要提供分片上傳和文件合并接口。
1. 組件結(jié)構(gòu)
首先,使用 iView 提供的 Upload
組件來構(gòu)建文件上傳界面,界面中包含一個選擇文件按鈕和一個上傳進(jìn)度條。在 Vue 的 data
中定義上傳所需的一些變量,例如文件分片大小、上傳進(jìn)度、分片的集合等。
<template> <div> <!-- iView的Upload組件 --> <Upload :action="uploadAction" :before-upload="beforeUpload" :on-progress="handleProgress" :on-success="handleSuccess" :on-error="handleError" :show-file-list="false" :headers="uploadHeader" > <Button>選擇文件</Button> </Upload> <div v-if="uploading"> <Progress :percent="uploadProgress"></Progress> </div> </div> </template>
在上面的代碼中,使用了 iView 的 Upload
組件來處理文件選擇,Progress
組件用來展示文件上傳的進(jìn)度。before-upload
用于文件上傳前的預(yù)處理,on-progress
用來更新進(jìn)度條,on-success
和 on-error
用來處理上傳成功或失敗的回調(diào)。
2. 數(shù)據(jù)結(jié)構(gòu)
data() { return { uploadHeader: { Authorization: localStorage.token, // 上傳請求的授權(quán)頭 Accept: '*/*' // 允許所有類型的響應(yīng) }, fileName: '', // 存儲文件名 fileSize: 0, // 存儲文件大小 chunkSize: 5 * 1024 * 1024, // 每個分片的大小,這里設(shè)置為5MB fileChunks: [], // 存儲文件的所有分片 uploading: false, // 是否正在上傳 uploadProgress: 0, // 上傳進(jìn)度 currentChunkIndex: 0, // 當(dāng)前上傳的分片索引 uploadAction: `${this.baseURL}/xxxx`, // 上傳分片的API uploadActionMerge: `${this.baseURL}/xxx`, // 合并分片的API }; }
在 data
中,定義了上傳的必要參數(shù),包括文件名、文件大小、分片大小、上傳進(jìn)度等。uploadAction
和 uploadActionMerge
分別表示上傳分片和合并文件的 API 地址。
3. 處理文件上傳前的操作
當(dāng)文件被選中后,觸發(fā) before-upload
回調(diào)函數(shù),在該函數(shù)中我們進(jìn)行文件的驗(yàn)證和分片處理。
// 上傳前的驗(yàn)證和分片操作 beforeUpload (file) { // 如果需要做格式驗(yàn)證,大小檢查等,可以在這里添加驗(yàn)證邏輯 this.fileName = file.name; // 記錄文件名稱 this.fileSize = file.size; // 記錄文件大小 // 調(diào)用分片處理方法 this.chunkFile(file); return false; // 返回false表示不直接上傳,手動上傳 },
4. 分片處理
chunkFile(file) { const totalChunks = Math.ceil(file.size / this.chunkSize); // 計算分片數(shù)量 this.fileChunks = []; // 清空分片數(shù)組 // 循環(huán)切割文件為多個分片 for (let i = 0; i < totalChunks; i++) { const start = i * this.chunkSize; const end = Math.min(start + this.chunkSize, file.size); const chunk = file.slice(start, end); this.fileChunks.push(chunk); // 將當(dāng)前分片添加到分片數(shù)組 } this.uploading = true; // 設(shè)置上傳狀態(tài)為進(jìn)行中 this.uploadNextChunk(); // 上傳第一個分片 }
在 chunkFile
方法中,我們通過計算文件的總大小和每個分片的大小來確定分片數(shù)量,并將文件切割成多個分片。然后,我們將每個分片存儲在 fileChunks
數(shù)組中,并開始上傳第一個分片。
5. 上傳分片
上傳每個分片時,我們使用 FormData
來構(gòu)造上傳的表單數(shù)據(jù),并使用 axios
發(fā)送 HTTP 請求。
uploadChunk(chunk) { const clientId = this.generateClientId(); // 生成唯一的客戶端ID const formData = new FormData(); formData.append('file', chunk); // 添加分片 formData.append('clientId', clientId); // 客戶端ID formData.append('chunkId', this.currentChunkIndex); // 當(dāng)前分片索引 this.axios.post(this.uploadAction, formData, { headers: { 'Content-Type': 'multipart/form-data' }, onUploadProgress: (event) => { const hasUploadTotal = this.currentChunkIndex * this.chunkSize; const percent = Math.round((hasUploadTotal + event.loaded) * 100 / this.fileSize); // 計算上傳進(jìn)度 this.uploadProgress = percent; // 更新進(jìn)度 }, }).then(res => { if (res.data.code === 1) { this.currentChunkIndex++; // 上傳成功,增加分片索引 this.uploadNextChunk(clientId); // 上傳下一個分片 } else { this.$message.error('上傳失敗'); this.uploading = false; } }).catch(error => { this.$message.error('上傳失敗'); this.uploading = false; }); }
6. 合并文件
當(dāng)所有分片上傳完成后,我們需要調(diào)用后端接口來合并這些分片,最終生成完整的文件。
mergeFile(clientId, fileName) { const url = `${this.uploadActionMerge}&clientId=${clientId}&sourceName=${fileName}`; this.axios.post(url).then(({ data }) => { if (data.code === 1) { this.$message.success('上傳成功'); } else { this.$message.warning(data.message); } }).catch((err) => { this.$message.error('合并文件出錯'); }).finally(() => { // 重置狀態(tài) this.resetUploadState(); }); }
7. 生成客戶端ID
為了確保每次上傳都能被唯一標(biāo)識,我們使用當(dāng)前時間戳和隨機(jī)數(shù)生成一個客戶端ID。
generateClientId() { const timestamp = (+new Date()).toString(32); // 時間戳轉(zhuǎn)為32進(jìn)制 let randomStr = ''; // 隨機(jī)生成字符 for (let i = 0; i < 5; i++) { randomStr += Math.floor(Math.random() * 65535).toString(32); } return timestamp + randomStr; // 返回客戶端ID }
8. 上傳進(jìn)度
通過 onUploadProgress
回調(diào)函數(shù),我們可以在文件上傳過程中動態(tài)地更新進(jìn)度條,實(shí)時展示上傳進(jìn)度。
handleProgress(event) { const hasUploadTotal = this.currentChunkIndex * this.chunkSize; const percent = Math.round((hasUploadTotal + event.loaded) * 100 / this.fileSize); // 計算總上傳進(jìn)度 this.uploadProgress = percent; // 更新進(jìn)度條 }
9. 上傳成功和失敗處理
最后,我們還可以在上傳成功或失敗時,進(jìn)行相應(yīng)的處理。
handleSuccess(response) { this.$message.success('上傳成功'); this.uploading = false; } handleError(error) { this.$message.error('上傳失敗'); this.uploading = false; }
總結(jié)
通過以上步驟,成功實(shí)現(xiàn)了基于 Vue 和 iView 組件的分片上傳功能。主要流程包括:文件選擇、文件分片、逐個分片上傳、上傳進(jìn)度顯示以及文件合并等。該方案對于大文件上傳具有較好的穩(wěn)定性和效率,尤其適用于大文件的分片上傳場景。
到此這篇關(guān)于基于Vue 和 iView分片上傳功能實(shí)現(xiàn)(上傳組件)的文章就介紹到這了,更多相關(guān)vue iview分片上傳內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue+elementUI實(shí)現(xiàn)表單和圖片上傳及驗(yàn)證功能示例
這篇文章主要介紹了vue+elementUI實(shí)現(xiàn)表單和圖片上傳及驗(yàn)證功能,結(jié)合實(shí)例形式分析了vue+elementUI表單相關(guān)操作技巧,需要的朋友可以參考下2019-05-05在vue中使用回調(diào)函數(shù),this調(diào)用無效的解決
這篇文章主要介紹了在vue中使用回調(diào)函數(shù),this調(diào)用無效的解決,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08VUE項(xiàng)目運(yùn)行npm install報錯問題以及解決
在運(yùn)行Vue項(xiàng)目時遇到npm安裝錯誤可使用命令npminstall--legacy-peer-deps解決,若VsCode中無法運(yùn)行npm命令,則可能是IDE配置未生效,可嘗試重啟電腦或使用cmd命令行直接在項(xiàng)目目錄下運(yùn)行2024-10-10Vue3+X6流程圖實(shí)現(xiàn)數(shù)據(jù)雙向綁定詳解
這篇文章主要為大家詳細(xì)介紹了Vue3如何結(jié)合X6流程圖實(shí)現(xiàn)數(shù)據(jù)雙向綁定,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-03-03vue+node 實(shí)現(xiàn)視頻在線播放的實(shí)例代碼
這篇文章主要介紹了vue+node 實(shí)現(xiàn)視頻在線播放的實(shí)例代碼,代碼簡單易懂,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-10-10ElementUI實(shí)現(xiàn)el-table列寬自適應(yīng)的代碼詳解
這篇文章給大家介紹了ElementUI實(shí)現(xiàn)el-table列寬自適應(yīng)的詳細(xì)步驟,文中通過代碼示例給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-01-01