zoukankan      html  css  js  c++  java
  • 【elementUI系列】在elementUI中新建FormData对象组合上传图片和文件的文件对象,同时需要携带其他参数

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

    我的思路是:

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

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

    一、上传照片和其他参数

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


    (一)视图部分代码:

    <el-form-item prop="image" label="图片附件上传">
              <el-upload
                ref="upload"
                :action="uploadAction"
                :beforeUpload="beforeUploadPicture"
                :on-change="imageChange"
                list-type="picture-card"
                name="files"
                :data="paramsData"
                :limit="3"
                multiple
                :auto-upload="false"
                :on-preview="handlePictureCardPreview"
                :on-remove="handleRemovePicture">
                <i class="el-icon-plus"></i>
              </el-upload>
              <el-dialog :visible.sync="dialogVisible">
                <img width="100%" :src="dialogImageUrl" alt="">
              </el-dialog>
         </el-form-item>
    
     <el-button size="mini" type="primary" @click="confirm()">确 定</el-button>

    说明:

    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传递的文件对象。





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

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


    (一)视图部分代码

    <el-form-item prop="image" label="图片附件上传">
              <el-upload
                ref="uploadImage"
                :action="uploadAction"
                :beforeUpload="beforeUploadPicture"
                :on-change="imageChange"
                list-type="picture-card"
                name="files"
                :limit="3"
                multiple
                :auto-upload="false"
                :on-preview="handlePictureCardPreview"
                :on-remove="handleRemovePicture">
                <i class="el-icon-plus"></i>
              </el-upload>
              <el-dialog :visible.sync="dialogVisible">
                <img width="100%" :src="dialogImageUrl" alt="">
              </el-dialog>
            </el-form-item>
            <el-form-item prop="image" label="文件附件上传">
              <el-upload
                ref="uploadFile"
                class="upload-demo"
                name="files"
                :on-change="fileChange"
                :action="uploadAction"
                :on-preview="handlePreviewFile"
                :on-remove="handleRemoveFile"
                :before-remove="beforeRemoveFile"
                multiple
                :auto-upload="false"
                :limit="3"
                :on-exceed="handleExceedFile"
                :file-list="fileList">
                <el-button size="small" type="primary">点击上传</el-button>
                <!--<div slot="tip" class="el-upload__tip">只能上传文件,且不超过2M</div>-->
              </el-upload>
            </el-form-item>
    
     <el-button size="mini" type="primary" @click="confirm()">确 定</el-button>

    (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的

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

  • 相关阅读:
    简单马周游问题1152siicly
    Sicily 1155. Can I Post the lette
    POJ 1007
    给定2个大小分别为n, m的整数集合,分别存放在两个数组中 int A[n],B[m],输出两个集合的交集。
    算法1--
    GAN
    为什么ConcurrentHashMap是弱一致的
    手写HASHMAP
    千万级规模高性能、高并发的网络架构经验分享
    Web 通信 之 长连接、长轮询(转)
  • 原文地址:https://www.cnblogs.com/chengxs/p/10047376.html
Copyright © 2011-2022 走看看