• Element_文件上传&&多个文件上传


    官网:https://element-plus.gitee.io/zh-CN/component/upload.html

    单个文件上传

    <template>
    <el-upload
    	    ref="upload"
    	    action=" /object/radr/ballistic/localBallisticConvert"
    	    :data="uploadData"
    	    :before-upload="(file)=>{
    	      beforeUpload(file)
    	    }"
    	    :show-file-list="false"
    	  accept=".json"
    	>
    	<el-button
    	  type="primary"
    	  :disabled="isAction"
    	>
    	  加载文件2
    	</el-button>
    	</el-upload>
    </template>
    <script lang="ts" setup>
    import { ref } from 'vue'
    import type { UploadInstance } from 'element-plus'
    const uploadData = ref({
          file:null,
          latitude:null,
          launchDirection:null,
          localBallistic:null,
          longitude:null,
      });
    const fileName = ref()
    function beforeUpload(file){
           fileName.value = file.name,
            uploadData.value.file= file
     }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    多文件上传

    在ElementPlus中有手动上传的方法,具体实现是点击手动上传后,将多个文件进行单个上传,会触发多次请求

    <template>
      <el-upload
        ref="uploadRef"
        class="upload-demo"
        action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
        :auto-upload="false"
      >
        <template #trigger>
          <el-button type="primary">select file</el-button>
        </template>
    
        <el-button class="ml-3" type="success" @click="submitUpload">
          upload to server
        </el-button>
    
        <template #tip>
          <div class="el-upload__tip">
            jpg/png files with a size less than 500kb
          </div>
        </template>
      </el-upload>
    </template>
    <script lang="ts" setup>
    import { ref } from 'vue'
    import type { UploadInstance } from 'element-plus'
    
    const uploadRef = ref<UploadInstance>()
    
    const submitUpload = () => {
      uploadRef.value!.submit()
    }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    action="https://run.mocky.io" 请求 URL
    headers 设置上传的请求头部
    method 设置上传请求方法
    multiple 是否支持多选文件
    data 上传时附带的额外参数
    name 上传的文件字段名
    with-credentials 支持发送 cookie 凭证信息 boolean false
    show-file-list 是否显示已上传文件列表 boolean true
    drag 是否启用拖拽上传 boolean false
    accept 接受上传的文件类型(thumbnail-mode 模式下此参数无效) string
    on-preview 点击文件列表中已上传的文件时的钩子 (uploadFile: UploadFile) => void
    on-remove 文件列表移除文件时的钩子 (uploadFile: UploadFile, uploadFiles: UploadFiles) => void
    on-success 文件上传成功时的钩子 (response: any, uploadFile: UploadFile, uploadFiles: UploadFiles) => void
    on-error 文件上传失败时的钩子 (error: Error, uploadFile: UploadFile, uploadFiles: UploadFiles) => void
    on-progress 文件上传时的钩子 (evt: UploadProgressEvent, uploadFile: UploadFile, uploadFiles: UploadFiles) => void
    on-change 文件状态改变时的钩子,添加文件、上传成功和上传失败时都会被调用 (uploadFile: UploadFile, uploadFiles: UploadFiles) => void
    on-exceed 当超出限制时,执行的钩子函数 (files: File[], uploadFiles: UploadFiles) => void —
    before-upload 上传文件之前的钩子,参数为上传的文件, 若返回false或者返回 Promise 且被 reject,则停止上传。 (rawFile: UploadRawFile) => Awaitable
    before-remove 删除文件之前的钩子,参数为上传的文件和文件列表, 若返回 false 或者返回 Promise 且被 reject,则停止删除。 (uploadFile: UploadFile, uploadFiles: UploadFiles) => Awaitable
    file-list / v-model:file-list 默认上传文件 UploadUserFile[] []
    list-type 文件列表的类型 ‘text’ | ‘picture’ | ‘picture-card’ ‘text’
    auto-upload 是否自动上传文件 boolean true
    http-request 覆盖默认的 Xhr 行为,允许自行实现上传文件的请求 (options: UploadRequestOptions) => XMLHttpRequest | Promise —
    disabled是否禁用上传 boolean false
    limit 允许上传文件的最大数量 number

    1、我的思路

    • 需求

      • 想要将多个文件一起上传【备注:多个按钮上传多个文件,然后一起提交】
    • 问题

      • 预期效果
        在这里插入图片描述

      • 在提交之后默认将文件格式转换成了[object File],而不是(binary),因此使用单个文件单个上传
        在这里插入图片描述

    • 思路

      • 使用上传文件之前的钩子before-upload,在第一个文件要上传时返回false停止上传
      • 在第二个按钮点击上传时将上传文件之前的钩子before-upload的返回值为true,开始上传。
    • HTML

    <el-upload
           ref="upload"
           action=" /object/radr/ballistic/localBallisticConvert"
           :data="uploadData"
           :before-upload="(file)=>{
          	 return beforeUpload(file,'file1')
           }"
           :show-file-list="false"
          accept=".txt"
       >
       <el-button
         :disabled="isAction"
       >
       加载文件1
      el-button>
    el-upload>
    <el-upload
           ref="upload"
            action=" /object/radr/ballistic/localBallisticConvert"
            :data="uploadData"
            :before-upload="(file)=>{
              beforeUpload(file,'file2')
            }"
            :show-file-list="false"
          accept=".json"
        >
        <el-button
          type="primary"
          :disabled="isAction"
        >
          加载文件2
        el-button>
     el-upload>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • JS
    function beforeUpload(file,FLAG){
       if(FLAG ==='file1'){
           fileName.value.file1Name = file.name,
            uploadData.value.file1= file
       }
         if(FLAG === 'file2'){
            fileName.value.file2Name = file.name,
            uploadData.value.file2= file
       }
      return FLAG === 'file2' ? true :false
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2、优化思路一

    在网上搜索多篇文章之后,继续优化了我的思路
    这里不通过submit去提交,通过自己定义方法提交需要用到new FormData()对象,不了解FormData的朋友可以点击这里 FormData
    ,用element自带的on-changeon-remove可以很方便获取到fileList,最后把获取到的formData在通过接口传递即可
    引用来自:https://blog.csdn.net/wangyile4399/article/details/111315799

    • HTML

      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
    • 参数信息在这里插入图片描述

    • action参数必填,这里不走el-upload的默认上传,所以用不到这个地址,填空即可,因为是用自己封装方法提交,所以用不到on-success和on-error方法。

    • JS

      <script>
          import request from "@/utils/request"    // 此处为请求的封装方法,没有引用可以忽略
          export default {
              data() {
                  return {
                      fileList: [],   // 定义一个空数组
                  };
              },
              methods: {
                  // 文件状态改变时的钩子,添加文件、上传成功和上传失败时都会被调用,function(file, fileList)
                  handleChange(file, fileList) {
                      this.fileList = fileList
                  },
                  // 删除文件之前的钩子,参数为上传的文件和文件列表,若返回 false 或者返回 Promise 且被 reject,则停止删除。function(file, fileList)
                  handleRemove(file, fileList) {
                      this.fileList = fileList
                  },
                  //上传服务器
                  submitUpload() {
                      //判断是否有文件再上传
                      if (this.fileList.length === 0) {
                          return this.$message.warning('请选取文件后再上传')
                      }
                      // 下面的代码将创建一个空的FormData对象:
                      const formData = new FormData()
                      // 你可以使用FormData.append来添加键/值对到表单里面;
                      this.fileList.forEach((file) => {
                          formData.append('file', file.raw)
                      })
                      // 添加自定义参数,不传可删除
                      formData.append('parentId', '49')
                      formData.append('uploadType', '备料单')
                      formData.append('versions', 'v4.0')
       
                      //自定义的接口也可以用ajax或者自己封装的接口
                      request({
                          method: 'POST',
                          url: '/uploadFile',   //填写自己的接口
                          data: formData        //填写包装好的formData对象
                      }).then(res => {
                          if (res.data.code == 200) {
                              this.$message.success('上传成功');
                          } else {
                              this.$message.error('上传失败');
                          }
                          //清空fileList
                          this.fileList = []
                      })
                  },
              },
          };
      </script>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52

    3、优化思路二

    控制判断文件个数是否等于 fileList 的长度是否相等,相等再上传。
    引用来自:https://blog.csdn.net/qq_36022463/article/details/122723998

    • HTML
      在这里插入图片描述
    • JS
      在这里插入图片描述
      每次选择文件的时候设置为0 ,将最初的fileList存起来
      在这里插入图片描述
      不然每一个文件都会执行on-change,都会初始化fileList,就不能根据fileList判断是否有这个文件
      在这里插入图片描述

    3、优化思路三

    借助FormData的格式向后台传文件组

    • HTML

       <div class="upload-file">
        <el-upload
            accept=".xlsx"
            ref="upload"
            multiple
            :limit="5"
            action="http://xxx.xxx.xxx/personality/uploadExcel"
            :on-preview="handlePreview"
            :on-change="handleChange"
            :on-remove="handleRemove"
            :on-exceed="handleExceed"
            :file-list="fileList"
            :http-request="uploadFile"
            :auto-upload="false">
            <el-button slot="trigger" size="small" type="primary">选取文件el-button>
            <el-button style="margin-left: 133px;" size="small" type="success" @click="submitUpload">上传到服务器
            el-button>
            <div slot="tip" class="el-upload__tip">只能上传xlsx文件,且不超过100mdiv>
        el-upload>
       div>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
    • 修改:auto-upload="false"属性为false,阻止组件的自动上传
      :http-request="uploadFile"覆盖上传事件
      @click=“submitUpload”,给上传按钮绑定事件

    • JS

      data() {
      	return {
      		fileData: '',  // 文件上传数据(多文件合一)
      		fileList: [],   // upload多文件数组
      		uploadData: {
                fieldData: {
                  id: '', // 机构id,
                }
              },
      	}
      }
      
      
      methods:{
      		// 上传文件
      		uploadFile(file) {
      		    this.fileData.append('files', file.file);  // append增加数据
      		},
      		
      		// 上传到服务器
      	     submitUpload() {
      	            let fieldData = this.uploadData.fieldData;  // 缓存,注意,fieldData不要与fileData看混
      	            if (fieldData.id === '') {
      	                this.$message({
      	                    message: '请选择上传机构',
      	                    type: 'warning'
      	                })
      	            } else if (this.fileList.length === 0) {
      	                this.$message({
      	                    message: '请先选择文件',
      	                    type: 'warning'
      	                })
      	            } else {
      	                const isLt100M = this.fileList.every(file => file.size / 1024 / 1024 < 100);
      	                if (!isLt100M) {
      	                    this.$message.error('请检查,上传文件大小不能超过100MB!');
      	                } else {
      	                    this.fileData = new FormData();  // new formData对象
      	                    this.$refs.upload.submit();  // 提交调用uploadFile函数
      	                    this.fileData.append('pathId', fieldData.id);  // 添加机构id
      	                    this.fileData.append('loginToken', this.loginToken);  // 添加token
      	                    post(this.baseUrlData.url_02 + ":8090/personality/uploadExcel", this.fileData).then((response) => {
      	                        if (response.data.code === 0) {
      	                            this.$message({
      	                                message: "上传成功",
      	                                type: 'success'
      	                            });
      	                            this.fileList = [];
      	                        } else {
      	                            this.$message({
      	                                message: response.data.desc,
      	                                type: 'error'
      	                            })
      	                        }
      	                    });
      	                }
      	            }
      	        },
      	        
                  //移除
                  handleRemove(file, fileList) {
                      this.fileList = fileList;
                      // return this.$confirm(`确定移除 ${ file.name }?`);
                  },
      
                  // 选取文件超过数量提示
                  handleExceed(files, fileList) {
                      this.$message.warning(`当前限制选择 5 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);
                  },	      
      
      			  //监控上传文件列表
                  handleChange(file, fileList) {
                      let existFile = fileList.slice(0, fileList.length - 1).find(f => f.name === file.name);
                      if (existFile) {
                          this.$message.error('当前文件已经存在!');
                          fileList.pop();
                      }
                      this.fileList = fileList;
                  },
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60
      • 61
      • 62
      • 63
      • 64
      • 65
      • 66
      • 67
      • 68
      • 69
      • 70
      • 71
      • 72
      • 73
      • 74
      • 75
      • 76
      • 77
      • 78
      • 79
      • 80
    • 案例
      在这里插入图片描述

    原生js实现

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8" />
      <meta http-equiv="X-UA-Compatible" content="IE=edge" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <title>Document</title>
      <style>
        .file {
          position: relative;
          display: inline-block;
          background: #133d63;
          border: 0.1rem solid #99d3f5;
          border-radius: 0.2rem;
          padding: 0.2rem 0.6rem;
          overflow: hidden;
          color: #f0faff;
          text-decoration: none;
          text-indent: 0;
          line-height: 1.5rem;
          font-size: 0.8rem;
          margin-left: 7rem;
        }
    
        .file input {
          position: absolute;
          font-size: 0.8rem;
          right: 0;
          top: 0;
          opacity: 0;
          cursor: pointer;
        }
    
        .file:hover {
          background: #aadffd;
          border-color: #78c3f3;
          color: #004974;
          text-decoration: none;
        }
    
      </style>
    </head>
    
    <body>
      <div class="file">
        上传文件
        <input type="file" name="image" accept="image/*" onchange="upload()">
      </div>
      <script type="text/javascript">
        function upload (event) {
          var e = window.event || event;
          console.log(e)
          // 获取当前选中的文件
          var File = e.target.files[0];
          console.log(File);//打印值看下面图片,简单点的话我们直接把这个数据给后台处理就可以了
    
          var data = new FormData();
          data.append("file", File)
          let refreshToken = localStorage.getItem("token");
          axios
            .post(
              "http://202.101.162.69:8089/proxy/top/api/upload/oss",
              data,
              {
                headers: {
                  Authorization: refreshToken,
                },
              }
            )
            .then((res) => {
              if (res.data.code == 200) {
                this.$message({
                  message: "上传文件成功",
                  type: "success",
                  center: "true",
                  duration: 500,
                  customClass: "press",
                });
              } else {
                this.$message({
                  message: "上传文件失败",
                  type: "warning",
                  center: "true",
                  duration: 500,
                  customClass: "press",
                });
              }
            })
        }
    
    
      </script>
    </body>
    
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96

    在这里插入图片描述

  • 相关阅读:
    微信小程序实现类似于 vue中ref管理调用子组件函数的方式
    初探元宇宙存储,数据存储市场下一个爆点?
    Python xml.dom.minidom 读取XML元素
    maven的nexus私服搭建配置使用
    项目基于MVC的.Net技术类门户网站源码
    Redis 第五天
    抓包整理————ip 协议一[十二]
    解决Cannot resolve symbol ‘MybatisPlusInterceptor‘
    Array.from()的使用方法(数组去重,伪数组转为数组,数组浅克隆),Set和Map数据结构
    [Linux]文件系统
  • 原文地址:https://blog.csdn.net/qq_53810245/article/details/127881776