使用上传的时候,总是遇到各种问题,每次搜索之后用上便忘记,这里总结一下几种上传的方式和遇到的问题。
# 数据的绑定问题
上传组件有属性 file-list
, 但并没有双向绑定,主要还是用于显示已上传的文件使用的。传入对象数组,每个对象需要有 url 属性,某些样式的上传框还有 name 需要显示。
[ | |
{ | |
url: '', | |
name: '' | |
} | |
] |
上传之后这个数组并不会更新,因此需要自己维护上传的文件列表,尤其是已经上传的,和本次上传的。
由于各种事件,各种状态,更新维护数组容易混乱,最好还是在最后上传删除都完成后,通过 upload 组件的实例,拿到当前的文件列表:
this.$refs.elUpload.uploadFiles |
该数组保存了列表中的文件,此处需要判断文件是刚选择上传的,还是之前上传了通过 file-list 初始化的,刚上传的文件包含一个 response 属性,即上传接口返回的信息,可以借此获得文件的 url 。
# 删除文件
默认的列表方式将触发 on-remove
事件,可以进行相关处理,但在 list-type="picture-card"
类型中,单独设置了按钮进行删除,但没给删除的方法。
这里同样可以拿到组件的引用,通过 uploadFiles 数组进行文件移除:
handleRemove(file) { | |
const uploadFiles = this.$refs.elUpload.uploadFiles | |
const index = uploadFiles.indexOf(file) | |
if (index !== -1) { | |
uploadFiles.splice(index, 1) | |
} | |
} |
# 多文件上传 on-success 事件
选择多文件上传时,发现 on-success 仅触发了一次,后查找发现在上传后如果修改了 file-list 绑定的数组对象,会导致该问题。
这也是选择最后再读取组件对象的 uploadFiles 来保存文件的原因,要自己在上传中同时维护刚上传的文件和原来的文件列表,处理删除这些问题,会比较混乱,不如最后直接读取组件的文件列表。
# picture-card 样式的进度条
选择该样式后,上传没有进度条,点击去组件的源码看了下,可以自己增加一个进度条在模板中:
<el-upload | |
action="#" | |
list-type="picture-card" | |
:auto-upload="false"> | |
<i slot="default" class="el-icon-plus"></i> | |
<div slot="file" slot-scope="{file}"> | |
<img | |
class="el-upload-list__item-thumbnail" | |
:src="file.url" alt="" | |
> | |
<!-- 添加的进度条 --> | |
<el-progress | |
v-if="file.status === 'uploading'" | |
type="circle" | |
:stroke-width="6" | |
:percentage="parsePercentage(file.percentage)" | |
/> | |
<span class="el-upload-list__item-actions"> | |
<span | |
class="el-upload-list__item-preview" | |
@click="handlePictureCardPreview(file)" | |
> | |
<i class="el-icon-zoom-in"></i> | |
</span> | |
<span | |
v-if="!disabled" | |
class="el-upload-list__item-delete" | |
@click="handleDownload(file)" | |
> | |
<i class="el-icon-download"></i> | |
</span> | |
<span | |
v-if="!disabled" | |
class="el-upload-list__item-delete" | |
@click="handleRemove(file)" | |
> | |
<i class="el-icon-delete"></i> | |
</span> | |
</span> | |
</div> | |
</el-upload> |
# 图片卡片占不满
文档里给的 img 标签,如果图片是长方形的,图片卡片就不会占满,看着比较丑,这里用 el-image 来替代,设置 fit="cover",并将父 div 设置宽高为 100%:
<div slot="file" slot-scope="{file}" style="width: 100%;height: 100%;"> | |
<el-image | |
class="el-upload-list__item-thumbnail" | |
style="width: 100%;height: 100%;" | |
:src="file.url" | |
alt="" | |
fit="cover" | |
/> | |
... | |
</div> |