內容簡介
記錄了一次通過閱讀Element-UI源碼,利用hack手段,進入el-upload組件特定鉤子的方法。
為什么要這么做?
Element-UI是一款優秀的開源項目,但它也無法滿足所有的用戶場景。
當無法滿足的時候,我們可以選擇:
- 自己寫個組件
- 對element的組件進行改造
- hack方式
如果有把握,方法3絕對是代價最小,而且最穩妥的。
現狀是什么?
Element-UI的el-upload對文件的處理是按單文件進行的,無論你一次選中多少個文件,它都會對文件列表進行遍歷,依次上傳。
每一個文件都會走一遍完整的生命周期。
我的期望是什么?
因為業務需要,我需要支持一次選擇/拖拽多個文件,并將多個文件封裝到一個Formdata中,使用一次http(s)請求,完成多個文件的上傳。
當前組件為何無法滿足
上面的現狀描述了el-upload的實現機制,那就決定了我無法在一個方法中,獲得全部數據列表。(也不是完全不可以,在文件列表的最后一次觸發是,fileList即為全部數據列表,但無法確認什么時候是最后一次)
怎么辦?先讀讀源碼吧。
以下是Element-UI中,upload組件的相關業務代碼:
uploadFiles(files) {
if (this.limit && this.fileList.length + files.length > this.limit) {
this.onExceed && this.onExceed(files, this.fileList);
return;
}
let postFiles = Array.prototype.slice.call(files);
if (!this.multiple) { postFiles = postFiles.slice(0, 1); }
if (postFiles.length === 0) { return; }
postFiles.forEach(rawFile => {
this.onStart(rawFile);
if (this.autoUpload) this.upload(rawFile);
});
}
可以看到,源碼做了如下處理:當一些判斷結束后,立刻開始對postFiles進行forEach,依次處理上傳。
逃票了!
看到這,我很沮喪!Element-UI團隊居然沒有給我們留鉤子!
不對!等等!
也不是完全沒有鉤子,對吧?
比如說上面代碼里的onExceed鉤子,當文件上傳數量超過限制時,會直接進入該方法。而且帶上了全部文件……
咦?
怎么樣可以百分百進入該方法呢?
this.limit < 0 不就可以了?
解決的思路瞬間清晰:令limit = -1,那么便可以在組件的on-exceed鉤子中,獲取到全部的文件了!