element文件上传el-upload踩坑记录

1,250 阅读2分钟

实现:文件手动上传,点击确认时调用提交接口,将表单数据传入后端

<el-upload
  drag
  action="kkkk"
  class="upload-demo"
  ref="upload"
  :accept="item.accept"
  :http-request="(file) => getFile(file, item)"
  :auto-upload="true"
  :before-upload="(file) => beforeUpload(file, item)"
  :multiple="false"
  :limit="1"
>
  <i class="el-icon-upload"></i>
  <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
  <div class="el-upload__tip" slot="tip">{{ item.tip }}</div>
</el-upload>

手动上传最重要的是:http-request属性,他可以获取到file文件对象

http-request中的方法不会触发怎么解决?
1、action="abc"得这样写不能删!,action=""也可以这样写,
2:auto-upload=false” 这个要删掉才能触发http-request方法,因为action="abc"是这样写的,没action中没有包含上传链接。
3、在使用http-request方法的时候, :on-success, :on-error 指令是不会触发的。

// param是自带参数
getFile(param, item) {
  this.modelValue[item.prop] = param.file;
  this.$emit("input", { ...this.modelValue });
},

文件上传校验:before-upload

before-upload可以自定义参数,before-upload要与auto-upload配合,auto-upload为true才生效。
// 上传文件校验
beforeUpload(file, item) {
  if (file && file.size / 1024 / 1024 > item.limitSize) {
    this.$message.error(`文件大小不能超过${item.limitSize}`);
    return false;
  }
  if (file && item.accept && item.fileType.indexOf(file.type) == -1) {
    this.$message.error(`只能上传${item.accept}类型的文件`);
    return false;
  }
},

formdata表单数据上传至后端

我们一般上传使用的是[form表单提交],可以把所有表单元素的name与value组成一个queryString,提交到后台。这用jquery的方法来说,就是serialize;

但是上述的方式,只能传递一般的参数, 上传文件的文件流是无法被序列化并传递的。所以我们就可以使用到formdata对象,就可以轻松进行文件上传了。

const fd = new FormData();//参数格式的转换
fd.append("file", formData.file);////文件流以参数形式传给后端
fd.append("fileName", formData.fileName);
fd.append("version", formData.version);
fd.append("notes", formData.notes || "");

接口报错

原因:我将存放表单的对象formData用json进行了拷贝,导致了file文件对象数据丢失,只剩下了uid字段,所以获取不到文件流。

JOSN.parse、JSON.stringify深拷贝数据丢失问题(使用JSON深拷贝有哪些弊端)

9a995c50dba46c56da1e6a821025ade.png

### 使用JSON.parse(JSON.stringify())进行深拷贝 有哪些弊端

-   如果obj里有函数,undefined,则序列化的结果会把函数, undefined丢失。
-   如果obj里面存在时间对象,JSON.parse(JSON.stringify(obj))之后,时间对象变成了字符串。
-   如果obj里有NaNInfinity和-Infinity,则序列化的结果会变成null。
-   JSON.stringify()只能序列化对象的可枚举的自有属性。如果obj中的对象是有构造函数生成的,则使用JSON.parse(JSON.stringify(obj))深拷贝后,会丢弃对象的constructor。如果对象中存在循环引用的情况也无法正确实现深拷贝。
-   如果obj里有RegExpError对象,则序列化的结果将只得到空对象。