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

简介: 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>

多文件上传

在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>

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>
    
  • 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
    }
    

2、优化思路一

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

  • HTML

      <template>
          <el-upload
                  class="pop-upload"
                  ref="upload"
                  action=""
                  :file-list="fileList"
                  :auto-upload="false"
                  :multiple="true"
                  :on-change="handleChange"
                  :on-remove="handleRemove"
          >
              <el-button slot="trigger" size="small" type="primary">选取文件</el-button>
              <el-button style="margin-left: 10px;" size="small" type="success" @click="submitUpload">上传到服务器</el-button>
          </el-upload>
      </template>
    
  • 参数信息在这里插入图片描述
  • 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>
    

    3、优化思路二

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

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

3、优化思路三

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

  • HTML
```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文件,且不超过100m</div>
  </el-upload>
 </div>
```
  • 修改:auto-upload="false"属性为false,阻止组件的自动上传
    :http-request="uploadFile"覆盖上传事件
    @click=“submitUpload”,给上传按钮绑定事件

  • JS
    ```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;
            },
}
```
  • 案例
    在这里插入图片描述

原生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>

在这里插入图片描述

相关文章
|
存储 JSON 数据库
vue3中实现文件上传---通过element-plus的upload组件
vue3中实现文件上传---通过element-plus的upload组件
|
JavaScript
【ElementUI】Vue+ElementUI多文件上传,一次请求上传多个文件!
教大家一次请求,上传多个文件。 ElementUI如果是默认方案,上传多张图片并不是真正的一次上传多张,而是发送多次请求,一次请求携带一张图片。
1532 0
|
JavaScript 前端开发
el-upload上传文件
el-upload上传文件
1482 0
|
前端开发 JavaScript 安全
【前端相关】elementui使用el-upload组件实现自定义上传
【前端相关】elementui使用el-upload组件实现自定义上传
3510 0
|
安全 关系型数据库 Linux
一文教你搭建个人网盘filerun,拥有私人文件服务器
一文教你搭建个人网盘filerun,拥有私人文件服务器
一文教你搭建个人网盘filerun,拥有私人文件服务器
|
存储 前端开发 Java
Element el-upload 文件上传/图片上传/拖拽上传/附带参数/附带请求头部详解
文目录 1. 前言 2. 基本用法 2.1 前端部分 2.2 后端部分 2.3 获取后端返回信息 3. 外观功能介绍 3.1 拖拽上传 3.2 显示图片 3.3 设置文件列表样式 3.4 显示提示信息 4. 事件功能介绍 4.1 限制上传文件数量 4.2 限制上传文件类型和大小 4.3 移除文件处理 4.4 手动上传 5. 附带参数 6. 附带请求头部 7. 小结
8061 0
|
JavaScript
基于Vue2或Vue3实现任意上下左右拖拽悬浮的元素,且配置为自定义的全局指令
这篇文章介绍了如何在Vue 2或Vue 3项目中实现一个自定义的全局指令`v-dragSwitch`,用于创建可以任意方向拖拽并悬浮的元素,同时包含边界处理的逻辑。
4205 2
基于Vue2或Vue3实现任意上下左右拖拽悬浮的元素,且配置为自定义的全局指令
|
JavaScript
vue中使用echarts绘制双Y轴图表时,刻度没有对齐的两种解决方法
vue中使用echarts绘制双Y轴图表时,刻度没有对齐的两种解决方法
4164 0
|
前端开发 JavaScript 数据库
多个文件上传
多个文件上传
181 0