vue中使用webuploader做斷點續(xù)傳實現(xiàn)文件上傳功能
1、下載webuploader
npm i webuploader
2、導(dǎo)入并掛載到原型上
在main.js中導(dǎo)入,全局注冊,掛載到原型上方便調(diào)用
import WebUploader from 'webuploader'; Vue.prototype.WebUploader = WebUploader; import "webuploader/dist/webuploader.css";
掛載到原型上之后就可以通過 this.WebUploader 去調(diào)用 之所以還要導(dǎo)入 webuploader.css 文件,是因為這樣在初始化時,才會有正常的按鈕樣式,樣式不符合需求也可以通過自己寫樣式去覆蓋掉,否則初始化之后就只是一個type = file的input框,不方便調(diào)整樣式
3、md5校驗
上傳一半取消了,再次上傳,怎么接著上傳?就需要進(jìn)行md5校驗,后臺才知道原來這個文件之前已經(jīng)上傳過了,不需要重頭上傳
另外,md5的校驗必須要寫在初始化之前
// 斷點續(xù)傳的按鈕初始化之前調(diào)用 webUploadBeforeInit(chunkSize) { this.WebUploader.Uploader.register({ "before-send-file": "beforeSendFile", "before-send": "beforeSend", }, { // 時間點1:所有分塊進(jìn)行上傳之前調(diào)用此函數(shù) beforeSendFile: (file) => { let deferred = this.WebUploader.Deferred(); let Uploader = new this.WebUploader.Uploader() Uploader.md5File(file, 0, chunkSize).progress(percentage => { debugger; console.log("校驗MD5中...") }).then(md5 => { file.md5 = md5; file.uid = this.WebUploader.Base.guid(); // 進(jìn)行md5判斷 this.axios({ url: this.commonUrl + "/FileUploadController/checkFile", method: "get", params: { fileName: file.name, md5: file.md5, }, }).then(res => { let status = res.code; deferred.resolve(); switch (status) { case 0: // 表示上傳成功或者已經(jīng)上傳過了 // 忽略上傳過程,直接標(biāo)識上傳成功; Uploader.skipFile(file); file.pass = true; break; case 16: // 部分已經(jīng)上傳到服務(wù)器了,但是差幾個模塊。 file.missChunks = res.data; break; default: break; // 另外我這里,12表示未上傳,1表示添加失敗,這里不需要做其他處理 } }).catch((err) => { deferred.reject(); }); }); return deferred.promise(); }, beforeSend: (block) => { let deferred = this.WebUploader.Deferred(); // 當(dāng)前未上傳分塊 let missChunks = block.file.missChunks; // 當(dāng)前分塊 let blockChunk = block.chunk; if (missChunks !== null && missChunks !== undefined &&missChunks !== "") { let flag = true; for (let i = 0; i < missChunks.length; i++) { if (blockChunk === parseInt(missChunks[i])) { // 存在還未上傳的分塊 flag = false; break; } } if (flag) { deferred.reject(); } else { deferred.resolve(); } } else { deferred.resolve(); } return deferred.promise(); }, } ); },
4、封裝初始化方法
有關(guān)webuploader配置項、事件等,可詳細(xì)參考 WebUploader API文檔 - Web Uploader (baidu.com)
webUploadResume(opt, evt){ if(!(opt && this.isObj(opt))) return console.error("請傳類型為對象的配置項opt,pick必傳") // md5校驗在初始化之前 this.webUploadBeforeInit(opt.chunkSize || 10485760) // 初始化 let uploader = this.WebUploader.create({ // 文件上傳調(diào)的便是此接口 server: this.commonUrl + "/FileUploadController/breakpointUpload", method: opt.method || "post", // 這個外部是必傳,要選一個dom初始化,無法給默認(rèn)值。 // 可以直接給ID,如"#abc",可以是對象,如 // { // id:"#abc", // 雖然名是id,但實際也可以是類名或標(biāo)簽名 // innerHTML:"按鈕文字,可不傳", // multiple:true/false 是否多選, // } pick: opt.pick, // 制定對那個dom進(jìn)行初始化 // 指定上傳的哪些類型的文件 // { // title:"文字描述" , // extensions:"允許的文件后綴,不帶點,多個用逗號分割,比如gif,jpg,jpeg,bmp,png", // mimeTypes: "多個用逗號分割,如image/*或者.gif,.jpg,.bmp" // } accept: opt.accept || null, resize: opt.resize || false, // 不壓縮img auto: opt.auto || true, // 是否開啟自動上傳 threads: opt.threads || 1, // 上傳并發(fā)數(shù)。允許同時最大上傳進(jìn)程數(shù) chunked: opt.chunked || true, // 是否分片上傳 chunkSize: opt.chunkSize || 10485760, // 分片大小,以B為單位,這里是10M = 10 * 1024 * 1024 B chunkRetry: opt.chunkRetry || 2, // 如果某個分片由于網(wǎng)絡(luò)問題出錯,允許自動重傳多少次 duplicate: opt.duplicate || true, // 重復(fù)上傳,為了解決上傳一個后若上傳失敗,需再次上傳,會無反應(yīng) formData: opt.formData || {}, // 文件上傳請求的額外參數(shù) fileNumLimit: opt.fileNumLimit || undefined, // 驗證文件總數(shù)量, 超出則不允許加入隊列 fileSizeLimit: opt.fileSizeLimit || undefined, // 驗證文件總大小是否超出限制, 超出則不允許加入隊列 fileSingleSizeLimit: opt.fileSingleSizeLimit || undefined, // 驗證單個文件大小是否超出限制, 超出則不允許加入隊列 // 主要看接口是否需要token,不需要的話,下方headers可以去掉 headers:{ token: sessionStorage.tkn } }) // 綁定事件 // beforeFileQueued, 當(dāng)文件被加入隊列之前觸發(fā) // fileQueued, 當(dāng)文件被加入隊列以后觸發(fā) // filesQueued, 當(dāng)一批文件添加進(jìn)隊列以后觸發(fā) // startUpload, 當(dāng)開始上傳流程時觸發(fā) // stopUpload, 當(dāng)開始上傳流程暫停時觸發(fā) // uploadBeforeSend, 當(dāng)某個文件的分塊在發(fā)送前觸發(fā),主要用來詢問是否要添加附帶參數(shù) // uploadProgress, 上傳過程中觸發(fā),攜帶上傳進(jìn)度 // uploadSuccess, 當(dāng)文件上傳成功時觸發(fā) // uploadError, 當(dāng)文件上傳出錯時觸發(fā) // uploadComplete, 不管成功或者失敗,文件上傳完成時觸發(fā) // uploadFinished, 當(dāng)所有文件上傳結(jié)束時觸發(fā) // error, 當(dāng)validate不通過時,會以派送錯誤事件的形式通知調(diào)用者 // addFail, 當(dāng)add接口失敗后執(zhí)行(非webuploader插件所帶,為自定義) if(evt && this.isObj(evt)){ for(let k in evt){ if(k == "uploadError" || k == "uploadSuccess"){ uploader.on(k, (file, resp) => { this.axios({ url:this.commonUrl + "/FileUploadController/add", method:"post", data:{ fileName: file.name, // 文件名 suffix: file.ext, // 文件后綴 uploadStatus: k == "uploadSuccess"?1:0, }, }).then(res => { evt[k](res,file,resp) }).catch(err => { evt.addFail && evt.addFail(file, resp) }) }) }else if(k != "addFail"){ uploader.on(k, evt[k]) } } }else{ console.error("斷點續(xù)傳事件evt未傳或傳的類型錯誤") } },
5、調(diào)用封裝的初始化方法進(jìn)行初始化
<template> <div id="addFail"></div> </template> <script> data(){ return {} }, mounted(){ this.webUploaderInit() }, methods:{ webUploaderInit(){ // 封裝的方法也是掛載到原型上的,方便調(diào)用 this.$tu.webUploadResume({ pick: "#addFail", accept: { title: "rar,zip", extensions: "rar,zip", mimeTypes: ".rar,.zip", }, fileSizeLimit: 1073741824, // 總大小不超過1G },{ beforeFileQueued: this.beforeFileQueued, uploadProgress: this.uploadProgress, uploadSuccess: this.uploadSuccess, uploadError: this.uploadError, error: this.error, addFail: this.addFail, }) }, beforeFileQueued(file){ // 注意區(qū)分beforeFileQueued和uploadBeforeSend // beforeFileQueued是選擇文件時,即將加入要上傳的文件隊列但還沒加入時 // uploadBeforeSend是即將開始調(diào)用上傳接口,但還沒調(diào)用 }, uploadProgress(file, percentage){ // percentag,即上傳進(jìn)度 // 一般用法 percentag * 100 + "%" 或者 percentag * width + "px" }, // 注意我這里uploadSuccess和uploadError跟其他事件注冊不太一樣,所以接受參數(shù)與api文檔并不完全一致 uploadSuccess(res,file,resp){……}, uploadError(err,file,resp){……}, error(type){ // 當(dāng) type == "Q_EXCEED_SIZE_LIMIT",就意味著選中的文件總大小超過了設(shè)置的fileSizeLimit // 當(dāng) type == "Q_EXCEED_NUM_LIMIT",就意味著選中的文件數(shù)量超過了設(shè)置的fileNumLimit // 當(dāng) type == "Q_TYPE_DENIED",就意味著選中的文件不符合accept中設(shè)置的文件格式 // 另外,如果設(shè)置了 fileSingleSizeLimit,即使不符合也不會進(jìn)入到這里 // 因為如果選擇了A文件超過,B文件未超,那么會將A文件自動過濾掉,只將B加入到文件隊列 }, // 無論uploadSuccess還是uploadError都會調(diào)用add接口,那么add也可能會因為某些情況調(diào)用失敗 // 針對此情況,增加了自定義addFail方法,當(dāng)add接口調(diào)用失敗時會執(zhí)行下面方法 addFail(file, resp){……}, }, </script>
初始化成功之后,頁面便能看到這樣一個按鈕
點擊即可上傳。若樣式不符合需求,可以F12找到相關(guān)類名,進(jìn)行樣式覆蓋
外,在覆蓋樣式時,注意:
- 你看到的“斷點續(xù)傳”的按鈕樣式是,類名為webuploader-pick的div
- 而你點擊時,之所以能打開選擇文件的彈窗,并非是點擊了這個div,實際是點擊了下面的lable標(biāo)簽
- 所以,覆寫樣式時,注意label標(biāo)簽要和div的位置保持一致,否則就會出現(xiàn)點擊但沒有任何反應(yīng),因為只是點了div,并沒有點擊到label
以上就是vue中使用webuploader做斷點續(xù)傳的方法詳解的詳細(xì)內(nèi)容,更多關(guān)于vue webuploader斷點續(xù)傳的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
vue、react等單頁面項目部署到服務(wù)器的方法及vue和react的區(qū)別
這篇文章主要介紹了vue、react等單頁面項目部署到服務(wù)器的方法,需要的朋友可以參考下2018-09-09解決vue中監(jiān)聽input只能輸入數(shù)字及英文或者其他情況的問題
今天小編就為大家分享一篇解決vue中監(jiān)聽input只能輸入數(shù)字及英文或者其他情況的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-08-08詳解vuex中mapState,mapGetters,mapMutations,mapActions的作用
這篇文章主要介紹了vuex中mapState,mapGetters,mapMutations,mapActions的作用,需要的朋友可以參考下2018-04-04vue3項目配置按需自動引入自定義組件unplugin-vue-components方式
這篇文章主要介紹了vue3項目配置按需自動引入自定義組件unplugin-vue-components方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-03-03vue3動態(tài)路由刷新出現(xiàn)空白頁的原因與最優(yōu)解
頁面刷新白屏其實是因為vuex引起的,由于刷新頁面vuex數(shù)據(jù)會丟失,這篇文章主要給大家介紹了關(guān)于vue3動態(tài)路由刷新出現(xiàn)空白頁的原因與最優(yōu)解的相關(guān)資料,需要的朋友可以參考下2023-11-11Vue + Webpack + Vue-loader學(xué)習(xí)教程之相關(guān)配置篇
這篇文章主要介紹了關(guān)于Vue + Webpack + Vue-loader的相關(guān)配置篇,文中通過示例代碼介紹的非常詳細(xì),相信對大家具有一定的參考價值,需要的朋友們下面來一起看看吧。2017-03-03