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的

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

  • 相关阅读:
    win7下的vxworks总结
    ubuntu 无法获得锁 /var/lib/dpkg/lock
    项目中用到了的一些批处理文件
    win7下安装 WINDRIVER.TORNADO.V2.2.FOR.ARM
    使用opencv统计视频库的总时长
    January 05th, 2018 Week 01st Friday
    January 04th, 2018 Week 01st Thursday
    January 03rd, 2018 Week 01st Wednesday
    January 02nd, 2018 Week 01st Tuesday
    January 01st, 2018 Week 01st Monday
  • 原文地址:https://www.cnblogs.com/chengxs/p/10047376.html
Copyright © 2011-2022 走看看