Element-UI使用el-upload组件第二次上传无效问题,文件回显添加文件到elupload组件
1、第二次上次无效问题。
<el-upload :action="uploadAction" :auto-upload="false" list-type="picture-card" :file-list="fileList" :on-success="onSuccess" :on-error="onError" ref="upload" :headers="headers" :data="uploadData" > <p>点击上传</p> </el-upload> <el-button @click="submit">提 交</el-button>
手动上传设置
:auto-upload="false"不自动上传文件
手动提交
submit() { this.$refs.upload.submit(); }
问题:
编辑数据回显后再次点击提交,发现第二次上传无效
实际代码开发中,会发现第一次新增上传文件会触发请求接口,如果编辑回显数据后再点就没反应了,因为要数据回显,所以不能使用组件的clearFiles方法清除文件列表。
通过仔细研究对比初次文件上传数据,发现实际上是因为el-upload绑定的文件列表变量fileList中的每个文件对象的status属性值不是ready。
选择文件后还没上传,这时打印文件列表变量,显示每个文件对象的status值是ready。
上传文件后打印文件列表变量,根据上传情况,每个文件对象的status值会被更改为success,fail,uploading这三种,而只有ready值的文件对象会被this.$refs.upload.submit()提交。
问题定位到了,想继续上传文件,可以这样处理:
this.fileList.forEach(item => { item.status = "ready"; })
2、编辑数据回显后提交,报错[Vue warn]: Error in nextTick: "TypeError: Failed to execute 'append' on 'FormData': parameter 2 is not of type 'Blob'."问题。
在开发的时候表单里需要上传文件附件的功能。看了下官方的el-upload组件的使用方法,在修改表单的时候,el-upload组件的回显遇到了问题:
根据文档的理解,按照教程方法,向file-list里添加一个文件对象[{name: "aa", url: http:xxxxxxxx}]就可以。
发现组件里的文件列表一直显示不成功,后来重新new了一个File对象,成功在文件列表里显示成功,但是却在before-upload钩子函数中却找不到这个文件,打印传过来的参数file一直是undefined,而file-list里有这个文件对象,但是属性和其他文件对象千差万别。
思考:
调试到这里感觉向file-list加入自己new出来的文件对象并不是向upload组件上传文件,而是向el-upload的子组件上传文件,然后显示到对应div和file-list中。
这种行为和点击上传从本地选择文件进行上传数据流不一样,并不是把文件对象加入组件中。
在编辑数据回显的时候,假如对upload这个组件没有做任何更改,那么点击提交是不会通过beforeupload钩子函数的验证的,这说明组件里并没有文件对象,往file-list添加文件对象没有真正的添加进去。element-ui源码也会报错提示TypeError: Failed to execute 'append' on 'FormData': parameter 2 is not of type 'Blob'.
解决:
实际需求要在编辑表单回显的时候,把文件对象加入到组件中,用于通过beforeUpload钩子函数的验证和上传文件对象最后点击提交到后台。
官方文档里并没有提供手动加入file对象的方法,查询了很多资料发现也没有关于加入文件到el-upload组件的明确方法和内容。
后面自己抽时间看了下源码,发现源码有个handleStart方法用于获取增加文件对象,根据前面提到的url路径问题,用xmlhttprequest方法请求到这个文件对象,然后用handleStart方法成功将文件添加到组件中,通过并触发了钩子函数验证,成功传给后台接口。代码如下:
//给upload组件添加文件 addDataFile(url, file) { var blob =null; var xhr = new XMLHttpRequest(); xhr.open("POST", url); xhr.setRequestHeader('Accept', '*/*'); xhr.responseType = "blob"; xhr.onload = () => { blob = xhr.response; let File = new File([blob], file, {type: '**********'});//自己定义文件类型 console.log(File,'File'); //el-upload组件的添加文件方法 this.$refs.upload.handleStart(File); }; xhr.onerror = (e) => { }; xhr.send(); },
最后:
通过上面代码调试,可以发现回显数据也是文件流了,页面不会再报错了,和新增提交的文件流相同了。后面开发过程中如果数据和业务实际数据有出入大家自行调整处理就好了,我也懒得改了。。。。。
更多推荐
所有评论(0)