elementUI upload组件踩坑

                <el-upload
                  action="#"
                  class="upload-demo"
                  accept="image/gif,image/jpeg,image/jpg,image/png,"
                  :on-change="fileChange"
                  :http-request="requestUpload"
                  list-type="picture-card"
                  :drag="true"
                  :on-remove="removeFile"
                  :limit="1"
                  :file-list="fileList"
                  style="display: inline-block; width: 360px"
                >
                  <i slot="default" class="el-icon-plus"></i>
                </el-upload>

action

官网说的是上传的服务器地址。但是不好用。不方便自定义上传的方式和传参。注意如果action的值不是# 或者 none 后面自定义的函数 http-request将不会调用

scope-slot file

我看了网上说可以在 el-upload中间写slot 自定义上传之后显示,添加,预览按钮,下载按钮,删除按钮等。比如:

<el-upload
    action="#"
     class="upload-demo"
     accept="image/gif,image/jpeg,image/jpg,image/png,"
     :on-change="fileChange"
     :http-request="requestUpload"
     list-type="picture-card"
     :drag="true"
     :on-remove="removeFile"
     :limit="1"
     :file-list="fileList"
     style="display: inline-block; width: 360px"
   >
   <i slot="default" class="el-icon-plus"></i>
                
	<div slot="file" slot-scope="{ file }">
	 <img
	    class="el-upload-list__item-thumbnail"
	    :src="
	      (file.response && file.response.imageUrl) || require('@/assets/image/default.png')
	    "
	    alt=""
	  />
	  <span class="el-upload-list__item-actions">
	    <span class="el-upload-list__item-preview">
	      <i
	        class="el-icon-zoom-in"
	        @click="handlePictureCardPreview(file)"
	      ></i>
	    </span>
	    <!-- <span
	        v-if="!disabled"
	        class="el-upload-list__item-delete"
	      >
	        <i
	          class="el-icon-download"
	          @click="handleDownload(file)"
	        ></i>
	      </span> -->
	    <!-- <span class="el-upload-list__item-delete">
	      <i
	        class="el-icon-delete"
	        @click="handleRemove(file)"
	      ></i>
	    </span> -->
	  </span>
	</div>
</el-upload>

然后发现没有必要,并且多了很多的逻辑。组件自带的会把上传好的图片预览出来,不使用后端返回的url。自带一个删除按钮,够用了。

on-change

发现这个属性特别好用,只要文件的状态发生改变,都可以获取到最新的file和fileList。可以每次在获取最新的file的时候,做逻辑,

auto-upload

自动上传:弹开文件夹,选中文件后自动上传,这里自动调用 http-request 自定义的方法进行上传。默认是开启的。如果想在点击确定提交表单的时候上传file对象到服务器,就关闭。

http content-type

默认是 application/json 现在上传的是文件二进制流。不用专门设置 content-type 为 form-data 浏览器会自动识别 。

    fileChange(file, fileList) {
      console.log(file, fileList);
      this.fileList = fileList
      let fileType = file.name.substring(file.name.lastIndexOf(".") + 1);
      if (
        fileType !== "jpeg" &&
        fileType !== "jpg" &&
        fileType !== "png" &&
        fileType !== "gif"
      ) {
        this.fileList = [];
      }
      this.currentFile = file;
     //this.headImgUrl = URL.createObjectURL(this.currentFile.raw); 后端直接返回了imageUrl 不用设置了
    },
    // 自定义实现上传覆盖默认的方法
    requestUpload(params) {
    // params.file 也是当前上传的文件
      const that = this;
      let file = this.currentFile.raw;//注意 .raw
      let fileType = file.name.substring(file.name.lastIndexOf(".") + 1);
      if (
        fileType !== "jpeg" &&
        fileType !== "jpg" &&
        fileType !== "png" &&
        fileType !== "gif"
      ) {
        return this.$message.error("文件格式有误,请上传图片!");
      }
      console.log(params, "requestUpload");
      let formData = new FormData();
      formData.append("file", file);
      // return new Promise((resolve) => {
      // 如果返回的是 promise resolve的值会在 fileChange函数中的.response中获取到! 不返回promise也能用
        that.$api.XXX(formData).then((res) => {
          if (res.code == "200") {
            that.$message.success(res.message || "上传成功");
            that.form.imageUrl = res.imageUrl;
            // resolve(res, "res---------"); //被 fileChange response获取
          } else {
            that.$message.error(res.message || "上传失败");
            // resolve(res, "res---------");
          }
        });
      // });
    },
    removeFile(file, fileList) {
      console.log(file, fileList);
      this.fileList = fileList;
    },

limit

只允许上传一个图片,limit是1,如果再上传图片就不会走 http-request 自定义方法了,鸡肋,只能点击删除上传过图片,调用removeFile方法,然后再重新上传。一般情况下是第二张图片替换第一张图片,但是我这边是上传接口单独写的,(其实可以在fileChange 中获取到当前最新的图片,然后赋值给一个值 currentFile,提交的时候再提交后后端,auto-upload为false),就先这样不换了吧。目前的考虑就是每次选中一张就上传到服务器,服务器上会很多图片,其实提交表单的时候一起提交file最好。并且在删除图片的时候,应该把服务器上的图片也给删除,这样省去很多垃圾文件,空间也能最大化利用。

objectURL = URL.createObjectURL(object);

刚开始设计的时候,我以为必须后端返回一个url才可以预览,然后发现了还有这个方法,object就是上传的file对象(object:用于创建 URL 的 File 对象、Blob 对象或者 MediaSource 对象。),返回值是类似这样的url:blob:http://localhost:8000/257b74da-ccf3-4b2b-b7b6-281fcb4cae17。这样就不需要后端在上传成功的时候返回imageUrl给前端了。

后面还要优化 待更新。。。。

最后感谢这篇文章给我很多启发:https://blog.csdn.net/qq_42394457/article/details/96769170

你可能感兴趣的:(elementui,前端,javascript)