资讯专栏INFORMATION COLUMN

【elementUI系列】使用elementUI调用一次接口同时上传图片和文件,同时需要携带其他参数

lavor / 3263人阅读

摘要:今天有一个坑,同时要上传图片和文件,而且图片要展示缩略图,文件要展示列表。我的思路是首先,只上传附件照片,这个直接看的官方例子就行,不仅仅上传附件照片,还同时上传其他参数。然后,再做上传照片和文件,上传其他参数,其实也就是文件合并。

今天有一个坑,同时要上传图片和文件,而且图片要展示缩略图,文件要展示列表。

我的思路是:

首先,只上传附件照片,这个直接看ele的官方例子就行,不仅仅上传附件照片,还同时上传其他参数。

然后,再做上传照片和文件,上传其他参数,其实也就是文件合并。

一、上传照片和其他参数

页面样式大约就是这样的,参数有优先级,发生时间,服务单名称,服务单描述,图片附件上传。

(一)视图部分代码:

      
        
      
      
        
      
 

确 定
说明:

1、action变量为后端图片接口的地址

2、beforeUpload方法是指的上传之前触发的函数,可以用来做前端文件格式判断,文件大小判断

3、on-change方法是指每次选择文件都会触发函数,可以用来前端删除和添加照片

4、list-type属性指的是照片picture-card展示的方式

5、name指的是上传的文件字段名,这是后端确认文件流的字段名,可以随便写

6、data属性指的是上传时附带的额外参数,这是指的其他参数

7、limit属性指的是上传文件的个数极限。

8、multiple属性指的是可以每次多选文件,true为多选,false为单选

9、auto-upload属性指的是自动上传的,true为可以自动上传,false为不可以自动上传

10、on-preview方法指的是查看缩略图的方法

11、on-remove方法指的是删除文件的方法

12、ref绑定dom元素

(二)data部分代码

data () {

return {
  selectedCategorySpe: this.selectedCategory,
  serviceForm: {
    title: "",
    desc: "",
    priority: "",
    occurDate: ""
  },
   dialogImageUrl: "",
   dialogVisible: false,
  uploadAction: "/inner/event/order/submit/submit" + "&accessToken=" + this.$store.getters.token
}

},

(三)computed部分代码

computed: {

...mapGetters([
  "constConfig"
]),
paramsData: function () {
  let params = {
    eventCategory: this.selectedCategorySpe.categoryId,
      priority: this.serviceForm.priority,
      title: this.serviceForm.title,
      dsc: this.serviceForm.desc,
      occurDate: this.serviceForm.occurDate
  }
  return params
}

},
使用computed实现实时监测paramsData的值,只要selectedCategorySpe.categoryId,serviceForm.priority,serviceForm.title

,serviceForm.desc,serviceForm.occurDate中只有一个变化,都会重新计算paramsData的值。

(四)methods部分方法
beforeUploadPicture(file){
  const isImage = file.type == "image/png" || file.type == "image/jpg" ||  file.type == "image/jpeg" || file.type == "image/bmp" || file.type == "image/gif" || file.type == "image/webp";
  const isLt2M = file.size <  1024 * 1024 * 2;
  if (!isImage) {
    this.$message.error("上传只能是png,jpg,jpeg,bmp,gif,webp格式!");
  }
  if (!isLt2M) {
    this.$message.error("上传图片大小不能超过 2MB!");
  }
  return isImage && isLt2M;
},
handlePictureCardPreview(file) {
  this.dialogImageUrl = file.url;
  this.dialogVisible = true;
},
handleRemovePicture(file, fileList) {
  console.log(file, fileList);
},
imageChange(file, fileList, name) {
  console.log(file, fileList);
},

confirm(){

this.$refs.upload.submit();
}

说明:confirm使用ref的绑定的upload,紧接着调用form的表单的submit方法。这个vue已经封装好了,这时候传的参数可以看到post传递的文件对象。

二、同时上传图片和文件,并且图片可以看缩略图文件显示成列表

但是当你出现这样的需求的时候,一脸蒙蔽

(一)视图部分代码

      
        
      
      
        
      
    
    
      
        点击上传
        
      
    

确 定

(2)data部分数据
data () {
    return { 
      selectedCategorySpe: this.selectedCategory,
      serviceForm: {
        title: "",
        desc: "",
        priority: "",
        occurDate: "",
      },
      images: {},
      files: {},
      dialogImageUrl: "",
      dialogVisible: false
    }
  },
(3)method部分数据
beforeUploadPicture(file){
     const isImage = file.type == "image/png" || file.type == "image/jpg" ||  file.type == "image/jpeg" || file.type == "image/bmp" || file.type == "image/gif" || file.type == "image/webp";
      const isLt2M = file.size <  1024 * 1024 * 2;
      if (!isImage) {
        this.$message.error("上传只能是png,jpg,jpeg,bmp,gif,webp格式!");
      }
      if (!isLt2M) {
        this.$message.error("上传图片大小不能超过 2MB!");
      }
      return isImage && isLt2M;
    },
    handlePictureCardPreview(file) {
      this.dialogImageUrl = file.url;
      this.dialogVisible = true;
    },
    handleRemovePicture(file, fileList) {
      console.log(file, fileList);
    },
    imageChange(file, fileList, name) {
      console.log(file, fileList);
      this.imageList = fileList;
      this.images["images"] = fileList;
    },

    handleRemoveFile(file, fileList) {
      console.log(file, fileList);
    },
    handlePreviewFile(file) {
      console.log(file);
    },
    handleExceedFile(files, fileList) {
      this.$message.warning(`当前限制选择 3 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);
    },
    beforeRemoveFile(file, fileList) {
      return this.$confirm(`确定移除 ${ file.name }?`);
    },
    fileChange(file,fileList) {
      console.log(file, fileList);
      this.fileList = fileList;
      this.files["files"] = fileList;
 },
  confirm(){
          let wfForm = new FormData();
          wfForm.append( "eventCategory",this.selectedCategorySpe.categoryId)
          wfForm.append( "priority",this.serviceForm.priority)
          wfForm.append( "title",this.serviceForm.title)
          wfForm.append( "dsc",this.serviceForm.desc)
          wfForm.append( "occurDate",this.serviceForm.occurDate)
          Object.entries(this.images).forEach(file => {
            file[0].forEach(item => {
              // 下面的“images”,对应后端需要接收的name,这样对图片和文件做一个区分,name为images为图片
              wfForm.append("images", item.raw)
              // wfForm.append(item.name, file[0])
            })
          })
          Object.entries(this.files).forEach(file => {
            file[0].forEach(item => {
              // 下面的“files”,对应后端需要接收的name,name为files为文件
              wfForm.append("files", item.raw)
              //wfForm.append(item.name, file[0])
            })
          })
          createEventOrder(wfForm).then( res => {
            console.log(res, "res")
            if(res.retValue === 1){
              this.$message.success( "成功创建服务单" );
              this.handleClose()
            }else{

            }
          })

    }

说明一下,新建了this.files存文件列表,this.images存图片列表。在confirm中新建一个FormData对象,使用append方法将参数变量加到数据对象中,和文件对象。最后将FormData对象传给后端。

传递的参数截图如下:

这回对images和files,图片和文件做区分,后端也需要做个判断,其他的参数不需要的参数可以选择不传,需要增加新的参数,使用append的方法添加。

2019.07.11【说明】

根据评论中提到的问题

 this.files[""] = fileList;

意义不大,这个就是想用一个对象存那个文件对象,对象需要一个name,自己取一个,也可以为空。改成这样也行:

 this.files["files"] = fileList;

这样做的目的是如果你的文件上传和图片上传用一个this.fileImage对象的话,在最后包装formData的时候可以通过对象的name区分,哪个是文件,哪个是图片,用一次

Object.entries(this.images).forEach 

就可以把formData包装好,更符合前端的高复用,低代码的思想。

我怕有人理解不了这个,我还是补充一下代码:

(2)data部分数据(新增一个fileImage)

fileImage: {},

(3)methods中修改这块

1、图片上传的这块修改为

if(isImage && isLt2M){  
    this.imageList = fileList;  
    this.fileImage["images"] = fileList;}else{  
    fileList.splice(-1,1);
}

2、文件上传的这块修改为

if(!isImage && isLt2M){  
    this.fileList = fileList;  
    this.fileImage["files"] = fileList;}else{  
    fileList.splice(-1,1);
}

3、提交那块,把两个forEach合并成一个,然后直接取对象的name最为formData的name。

Object.entries(this.fileImage).forEach(file => {      file[1].forEach(item => {    
        wfForm.append(file[0], item.raw)    
    })
})

最后也可以看到,也是ok的

【欢迎关注,有什么问题,欢迎提出,我看到有空就回答】

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/99795.html

相关文章

  • 基于vue-elementui图片文件上传的高阶使用分享

    摘要:前言要求图片上传支持多图片上传多浏览器图片格式判断多图片同时上传通过防并发设置防止可能出现的覆盖图片实时上传后支持在新窗口中打开查看使用注意代码中是页面中存在循环很多上传项,我为了省事直接复制粘贴的实现,如果单项上传就不用考虑了 前言 要求:1、图片上传支持多图片上传 +多浏览器图片格式判断;2、多图片同时ajax上传 通过防并发设置防止可能出现的覆盖;3、图片实时上传后支持 在新窗口...

    xi4oh4o 评论0 收藏0
  • 封装框架的实践

    摘要:最近在尝试着封装一个框架,碍于种种原因,先从简单的入手吧。基于和封装的框架,集成数据存储字体图标库拓展语言网络请求等模块,为了让业务开发更专注于数据驱动。 最近在尝试着封装一个框架,碍于种种原因,先从简单的入手吧。基于vue和elementUI封装的框架,集成 数据存储localforage、字体图标库font-awesome、css拓展语言scss、网络请求axios等模块,为了让业...

    Dogee 评论0 收藏0
  • 基于elementUI实现图片预览组件

    摘要:如果插件是一个对象,必须提供方法。当方法被同一个插件多次调用,插件将只会被安装一次。的插件应当有一个公开方法。不用,去掉这个属性,但是会污染全局样式,可配合或者推荐,所有样式写在当前组件或下面组件源码放大图片更多组件点击这儿 这是一个简单的点击图片预览的组件顺便记录一下写组件期间踩的vue中scope的坑~showImg(https://segmentfault.com/img/bVb...

    iOS122 评论0 收藏0
  • 聊一聊前端换肤

    摘要:之前在做网站换肤,所以今天想聊聊网站换肤的实现。一般实现如上图,我们会看到在某些网站的右上角会出现这么几个颜色块,点击不同的颜色块,网站的整体颜色就被替换了。 之前在做网站换肤,所以今天想聊聊网站换肤的实现。网页换肤就是修改颜色值,因此重点就在于怎么来替换。 一般实现 showImg(https://user-images.githubusercontent.com/12515800/...

    CocoaChina 评论0 收藏0
  • elementUI源码修改的爬坑之旅

    摘要:今天由于项目需要,想在组件上做一些变动和修改,我修改了的源代码,发布到上去成功使用,记录下过程中所碰到的问题。最后进行上传上传完成要是报各种看不懂的错误很大可能是包名重复。到项目中将项目中的中的中的修改为你的包名你的版本号。 今天由于项目需要,想在Tree组件上做一些变动和修改,我修改了elementUI的源代码,发布到npm上去成功使用,记录下过程中所碰到的问题。 下面简单记录下过程...

    _ipo 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<