项目中要实现一个文本上传和多图片上传的功能,如图所示:
乍一看,真尼玛简单。直接上代码布局:
上传图片
主要看图片上传也就是 upload部分。elementui的action可以自动提交到某个服务地址,但是注意 这里是需要手动提交的。
和后台沟通之后,确认图片使用formdata的形式进行传输,而上边的form表单以post参数的形式传递。ok!表单的很好处理,很简单,主要看图片以formdata的形式传递。
首先,拿到每个图片也就是 file 的信息不难:
// 对应上边的文件上传 获取当前文件信息
fileChange (file, fileList) {
//console.log('filechange',file);
if (file.size>300*1024) {
alert(`图片尺寸不能大于300KB!`);
let index = fileList.findIndex(item => item.uid === file.uid);
fileList.splice(index,1);
} else {
this.fileList.push(file);
}
},
console.log('filechange',file);打印出来图片的信息:
嗯,这就是当前上传的图片信息。这么多字段信息,也不知道该如何是好,毕竟咱也不知道这些信息是如何存储在服务器上的。但是既然你是一个对象,而我又在使用formdata 多图片文件上传,为什么不这么做呢?
开始用formdata传输。
// 大概意思写一下
let formdata = new FormData();
// 所有图片的集合 把所有文件push进一个数组中
let list = [].push(file);
// 开始组装formdata
formdata.append('images',list);
// 开始传输 很完美 ---------
post('upload/file',params).then(res => {
// 没有任何反应 ---------------------------------------
console.log(res)
})
怎么会呢?后台日志显示 params也正确传输接收到了,图片没有接受到?那么问题肯定处在formdata上边!!!
找一下 Mdn formdata:https://developer.mozilla.org/zh-CN/docs/Web/API/FormData
看看,说是你用formdata append的时候要注意啊!!!注意文件的类型 应该是File。那么在图片中,有没有这类的数据呢??
就是他了。 file.raw。
好了,这下我知道怎么上传了:
// 存储文件的 file.raw
let list = this.fileList.map(item => item.raw);
// 开始formdata上传
formdata.append('images',list);
但是这样还是不行!!查了好久啊,就不知道怎么回事,后来看到有人说,这要一个一个的上传,就是要循环遍历:
// 循环遍历 逐个添加 切记!!!这是重点啊
let list = this.fileList.map(item => item.raw);
for (var i=0,len=list.length;i
终于啊 network中看到了:
上传成功了终于!!很开心!
elementui 管理上传文件集合的 fileList 并不是响应式的!!!
这就很扯,对不对? 那这就意味着你点击删除按钮还要手动去找到当前删除项,把它删除了:
// 删除上传图片
handleRemove(file) {
let index = this.fileList.findIndex(fileItem => {
return fileItem.uid === file.uid
});
this.fileList.splice(index, 1);
},
这也是一个小坑吧,记录一下!!
另外有一点,当手动上传的时候,需要校验图片的格式,大小等信息,不合符要求的不要上传。
在element upload中,有一个钩子 before-upload ;可以在上传之前拦截一下,对图片的格式进行校验,不符合要求的返回false或者是reject。
但是经过试验,这个钩子只是在action自动提交的时候才会走这个方法,至于原因,还要等研究一下背后源码,但是手动提交的时候,用这个方法要小心了,没什么用。天无绝人之路,在filechange中也可以判断:
// 校验图片的大小和格式
fileChange (file, fileList) {
console.log('filechange',file);
// 在这里可以添加一些校验规则,符合规则的再添加进fileList 也是可以做到的 !!!
// 这里也很重要!!!!
if (file.size>300*1024) {
alert(`图片尺寸不能大于300KB!`);
let index = fileList.findIndex(item => item.uid === file.uid);
fileList.splice(index,1);
} else {
this.fileList.push(file);
}
},
基本上主要的就这些了,刚开始,两眼一抹黑啊,走了很多弯路。但是路走多了,就再也不怕黑!