element-ui组件el-upload自定义上传时界面抖动
描述
在使用 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 })
},