elementui组件中的el-upload文件/图片上传组件详解

项目中使用el-upload组件老是踩坑,解析一下文档的相关内容,以便后期需要的时候方便查阅。

相关参数解析

  • action 这个是必填的参数,填写请求地址,不填写会报错。 这里发送的请求一般为post请求
  • headers 设置上传的请求头部,可以直接动态绑定一个对象,设置Conent-type
  • data 为上传时附带的额外参数,可以用来修改上传接口的参数,例如绑定一个对象:data="{id:‘XXX’}"
  • multiple 是否可选多个文件上传
  • accept 限制上传文件的格式,注意这里只是选择文件时限制格式。其实用户还是可以点选“所有文件”选项,上传其他格式。如果需要在在上传时再次校验,则需要在:before-upload这个钩子绑定相应的方法来校验

相关问题解析

  • 文件上传后如何自定义上传列表样式
  • 使用自定义上传方式,即用http-request, 没有上传进度条,如何获取进度条
  1. 自定义上传方式
    	   <el-upload
              action
              multiple
              :http-request="startUpload"
              :file-list="fileList"
              :limit="5"
              :on-exceed="handleExceed">
              <el-button type="primary" class="outline-none mt-2" size="mini">上传图片</el-button>
              <div slot="file"></div>  // 主要是这里 插槽为空
            </el-upload>
            然后根据获取到的fileList 自定义上传列表样式
    
  2. 获取进度条
    // 自定义的上传实现函数
    handleHttpRequest(req) {
      // uid 作为唯一标识,方便上传完成后精准地替换图片 url
      const uid = req.file.uid 
      // 获取文件后缀名的函数
      const ext = getFileExt(req.file.name) 
      // 自定义 key ,上传时对图片的重命名会用到
      let keyname = this.$formatDate(new Date(), 'yyyyMMddhhmmss') + Math.floor(Math.random() * 1000) + '.' + ext
      // 压缩图片
      let newFile = null
      lrz(req.file, {
        quality: 0.7
      }).then(rst => {
        // 压缩完成
        newFile = rst.file
        // 创建form对象,上传七牛云所需要的参数
        const fileData = new FormData() 
        fileData.append('file', newFile)
        fileData.append('token', this.token)
        fileData.append('key', keyname)
        const config = {
          headers: { 'Content-Type': 'multipart/form-data' },
          // 这一段代码解决进度条不显示的问题,属于 axios 的使用知识。具体可以看文末的参考链接。
          onUploadProgress: progressEvent => {
           const percentCompleted = Math.floor((progressEvent.loaded * 100) / progressEvent.total)
           req.onProgress({ percent: percentCompleted })
         }
        }
        // 请求七牛云的接口,具体看自己怎么配置
        // 这里的 action 是请求地址,fileData 是请求发送的内容,config 是 http 的相关配置
        // 官方的请求地址可以查看这个链接:https://developer.qiniu.com/kodo/manual/1671/region-endpoint
        axios.post($config[this.bucket].action, fileData, config).then(res => {
          const url = `${$config[this.bucket].domain}/${res.data.key}`
          // 修改 url
          this.fileList.forEach((item) => {
            if (item.uid === uid) {
              item.url = url
            }
          })
          req.onSuccess(res)
        }).catch(err => {
          req.onError(err)
        })
      }).catch(err => {
        console.log(err)
      })
    }
    
  • 前端上传多个文件给后台
    1. 前后台协商好参数格式,如果是数组格式,举例
          // 改变事件
      	change(file){
      		this.file2.push(file.raw)
      	}
      	// 提交
      	var formData = new FormData()
      	for(var i = 0; i < this.file2.length; i++){
      		formData.append('file2', this.file2[i])
      	}
      	formData.append('city', this.input2)   // 添加其他字段
      	然后提交给后台的参数就是formData 
      
    2. 如果是字符串格式,举例
      // 数组格式转换字符串
      let arr = this.fileList.map(item=>{
      	return item.url
      }).join(',')
      
      // 字符串转数组
      let img = data.carousel.split(',')
      this.fileList = img.map(i =>{
      	let obj = {}
      	obj.url = i
      })
      

另外举一个验证实例

<!-- :limit="1" --> 
// 注意:最大允许上传个数:这里不要置为1,置为1有个问题就是:无论怎么选择文件,页面上展示的始终是第一次选择的文件
<el-upload
   ref="upload"
   class="uploadBox"
   :action="$config.baseURL + '/resource/upload/images'"
   :http-request="handleFileUpload"
   :on-change="handleChange" 
   :auto-upload="false"   // 注意1
   :before-upload="beforeFileUpload"  // 注意2:
   :file-list="fileList"   //  上传的文件列表
   :show-file-list="isShowList"  // 是否显示已上传文件列表
   :on-remove="handleFileRemove"
 >
   <el-button type="primary" size="small" >上传文件</el-button>
   <div slot="tip" class="el-upload__tip">注:仅支持zip格式压缩文件</div>
 </el-upload>
data() {
	return {
		isShowList:false,
		fileList:[]
	}
}

// 点击上传文件的按钮:
  handleChange(file, fileList) {
	 // 限制大小在10MB之内
      let isLt10M = file.size / 1024 / 1024 < 10
      if(!isLt10M) {
        this.$message.error("上传文件大小不能超过 10MB!")
      }
      // 限制类型只能为zip
      let isResPackage = file.raw.type.includes('zip') // 是否为zip格式
      if(!isResPackage){
        this.$message.error("请上传正确格式的文件!")
      }
      // 只有两个条件都满足的时候,根据文件数量判断
      if(isResPackage && isLt10M) {
       // 若文件>1个,则取第二个文件上传
        if(fileList.length > 1) {
          this.fileList = [fileList[fileList.length - 1]]
          this.$nextTick(()=>{
           // 主动去调用提交接口
            this.$refs.upload.submit();
          })
          // 若文件只有一个,直接上传
        } else {
          this.$refs.upload.submit();
        }
        // 若任意不满足一个条件,则不进行上传动作,根据数量判断
      } else {
       // 若文件>1,则保留第一个上传的文件
        if(fileList.length > 1) {
          this.fileList = [fileList[0]]
          // 当只有当前这一个文件时,则清空文件列表
        } else {
          this.fileList = []
          // this.$refs.upload.clearFiles() // 清除前端显示的文件列表
        }
      }
    },
  //文件上传条件 
  beforeFileUpload(file) {
    console.log(file,'file的信息')
    //注意:当有如题的需求时,可把这里的限制逻辑移至:on-change钩子中
    // let isResPackage = file.type.includes('zip') // 是否为zip格式
    // let isLt10M = file.size / 1024 / 1024 < 10
    // if(!isResPackage){
    //   this.$message.error("请上传正确格式的文件!")
    // }
    // if(!isLt10M) {
    //   this.$message.error("上传文件大小不能超过 10MB!")
    // }
    // return isResPackage && isLt10M;
  },
  // 自定义文件上传
    handleFileUpload(e) {
      console.log(e.file);
      this.isShowList = true;
      const that = this;
      this.ossUpload(e.file, {
        progress: (p, checkpoint) => {
          //因为是el-upload组件自定义上传,若需要显示进度条,必须手动调用进度条方法
          that.progress = p;
          e.onProgress({ percent: Math.floor(p * 100) }); // 触发el-upload组件的onProgress方法
        }
      })
        .then(result => {
          console.log(result);
          let index = result.res.requestUrls[0].indexOf("?");
          if (index != -1)
            that.advSubmitData.extFile = result.res.requestUrls[0].substring(0, index);
          else that.advSubmitData.extFile = result.res.requestUrls[0];
          that.$message.success("文件上传成功");
        })
        .catch(e => {
          that.$message.error("文件上传失败");
        });
    },
    //移除上传文件
    handleFileRemove(file, fileList) {
      console.log(file,fileList);
      this.advSubmitData.extFile = "";
    },  

<style lang="scss" scoped>
    .upload-demo {
      display: flex;
    }
    /deep/ .el-list-enter-active,
    /deep/ .el-list-leave-active {
      transition: none;
    }
 
    /deep/ .el-list-enter,
    /deep/ .el-list-leave-active {
      opacity: 0;
    }
    /deep/ .el-upload-list {
      height: 40px;
    }
</style>

上一篇:【shell】循环将字符串写入数组中?


下一篇:Spring核心接口Ordered的实现及应用