内容简介
记录了一次通过阅读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钩子中,获取到全部的文件了!