描述
在使用 element ui 的el-upload 自定義組件時,出現一個問題,上傳圖片時,圖片被擠到后面,上傳完成之后又回來的效果
在網上找了一圈,講的都比較片面,沒有講到本質原因,故做個記錄。
問題1:
使用 http-request 不能觸發 on-success 函數。
原因:
使用 http-request 時,需要返回 promise 對象,才會觸發 on-success。
解決方法:
將 ttp-request 函數結果返回 promise 對象即可。
問題2: 上傳抖動問題
原因:
一般使用自定義上傳圖片,即將后台返回的數據跟處理成 el-upload 需要的格式。
fileSuccess(res, file, filelist) { this.fileList.push({...res.data});
},
但是 el-upload 組件內部是這么處理的,大概意思就是,你上傳的時候,內部會有個對應的 fileList (uploadFiles),當你上傳的時候,內部 uploadFiles 會添加一個 file 信息,當你從外部 push 時,會進入 el-upload 的watch 如下圖
此時,push 進去 file 與 內部的 file 是不一樣的(uid)不一樣。所以導致組件內部的交互錯亂。
解決方法:
在 on-success 里直接賦值
onSuccess(res, file, filelist) { this.fileList = filelist; },
如果,外部是服務器傳回的地址,就在使用一個 tempList 來管理服務器的圖片上傳列表。然后其他的跟原來的組件沒啥區別,在做相應的操作的同時處理 tempList 。
完整代碼片段如下:
<el-upload action="#" :file-list="fileList" list-type="picture-card" :limit="limit" :multiple="multiple" accept="image/*" :before-upload="beforeUpload" :on-remove="fileRemove" :on-exceed="fileExceed" :on-success="fileSuccess" :http-request="fileUpload" :disabled="disabled" class="image-upload" />
// 上傳圖片
fileUpload(file) {
return new Promise(...);
},
// 上傳成功
fileSuccess(res, file, filelist) {
this.fileList = filelist;
this.tempList.push({...res.data});
},
// 刪除圖片
fileRemove(file) {
const index = this.fileList.findIndex(item => item.uid === file.uid);
if ( index === -1) {
this.$message.error('刪除的文件未找到');
return;
}
const fileName = this.tempList[index].fileName;
this.tempList.splice(index, 1);
// 服務器刪除對應的資源
commonApi.fileDelete({ fileName })
},