elementUI upload组件踩坑

javascript 复制代码
                <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 自定义上传之后显示,添加,预览按钮,下载按钮,删除按钮等。比如:

javascript 复制代码
<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 浏览器会自动识别 。

javascript 复制代码
    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

相关推荐
GreenTea1 小时前
一文搞懂Harness Engineering与Meta-Harness
前端·人工智能·后端
killerbasd3 小时前
牧苏苏传 我不装了 4/7
前端·javascript·vue.js
吴声子夜歌3 小时前
ES6——二进制数组详解
前端·ecmascript·es6
码事漫谈3 小时前
手把手带你部署本地模型,让你Token自由(小白专属)
前端·后端
ZC跨境爬虫3 小时前
【爬虫实战对比】Requests vs Scrapy 笔趣阁小说爬虫,从单线程到高效并发的全方位升级
前端·爬虫·scrapy·html
爱上好庆祝3 小时前
svg图片
前端·css·学习·html·css3
橘子编程4 小时前
JavaScript与TypeScript终极指南
javascript·ubuntu·typescript
王夏奇4 小时前
python中的__all__ 具体用法
java·前端·python
叫我一声阿雷吧4 小时前
JS 入门通关手册(45):浏览器渲染原理与重绘重排(性能优化核心,面试必考
javascript·前端面试·前端性能优化·浏览器渲染·浏览器渲染原理,重排重绘·reflow·repaint
大家的林语冰4 小时前
《前端周刊》尤大开源 Vite+ 全家桶,前端工业革命启动;尤大爆料 Void 云服务新产品,Vite 进军全栈开发;ECMA 源码映射规范......
前端·javascript·vue.js