vue+Element-Plus+Upload+axios多文件同时上传

在浏览器端上传文件时,为了防止恶意用户滥用上传功能,浏览器做了很多限制。

在使用element-plus时发现,虽然一次性选中了很多的文件,但是在接口调用时,仍然是按照单文件一个一个的上传的。以下将介绍如何突破这个限制,只调用一次接口就能上传所有的文件。

我这里的思想是借助Upload组件帮我们选中文件,然后文件上传的http请求我自己去实现,通过不断的实验发现可以使用Upload 的props:on-change、http-request来实现。具体流程如下

  1. 当我们选择了文件之后,会调用on-change函数,此函数的第一个参数UploadFile就是我们选中的文件对象,多个文件会多次调用on-change函数,基于此我使用了fileList:Array<UploadFile>来存储上传文件,并且在存储之后直接调用Upload上的方法handleRemove,直接将其从upload组件上删除,这样我们就将待上传的文件存储到fileList。
  2. 由于我们设置了upload组件的自动上传,所以在调用on-change函数之后会再调用http-request函数,这里我们自定义http请求,把请求拦截下来不交给upload组件执行上传操作,由于多个文件会多次调用http-request函数,所以我们在第一次调用之后就应该把fileList清空,并在调用自定义http请求之前判断fileList是否为空。
一、效果图

二、后端代码

三、html
<el-upload
  :show-file-list="false"
  :multiple="true"
  :limit="20"
  :auto-upload="true"
  :on-change="filechange"
  :http-request="customRequest"
  ref="uploadRef"
>
 <el-button icon="Upload" plain type="info">导入</el-button>
</el-upload>
 四、ts代码
//存放选中的文件
const fileList = ref<Array<UploadFile>>([])
//upload组件
const uploadRef = ref<any>(null)
//监听upload组件在文件状态变化时的钩子函数
//主要是将监听到的文件存入fileList (去重了)
function filechange(uploadFile: UploadFile, uploadFiles: UploadFiles) {
  if (fileList.value.length == 0) {
    fileList.value.push(uploadFile)
  }
  let contain = false
  for (const key in fileList.value) {
    const element = fileList.value[key]
    if (element.name === uploadFile.name && element.size === uploadFile.size) {
      contain = true
    }
  }
  if (!contain) {
    fileList.value.push(uploadFile)
  }
  //删除upload组件上文件的缓存
  uploadRef.value.handleRemove(uploadFile, uploadFiles)
}
//自定义的上传请求
function customRequest(options: UploadRequestOptions) {
  console.log('customRequest', options)
  if (fileList.value.length > 0) {
    //http 请求
    submit()
    //每次上传之后将文件清空,多个文件上传时,upload组件会多次调用customRequest方法,如果不清空会导致文件多次上传
    fileList.value = []
  }
}
//上传,uploadFiles是用axios实现的文件上传,函数定义往下看
function submit() {
  //fileList是UploadFile数组,真正上传时不需要他,而是uploadFile.raw
  const files = fileList.value.map((uploadFile) => uploadFile.raw)
  uploadFiles(files)
}
五、axios
import axios, { type AxiosInstance } from 'axios'

export function uploadFiles(option: Array<File>) {
  console.log('set', option)
  //浏览器对于文件上传默认会将文件拆分,分多次http请求服务器,
  //如果想要一次上传所有的文件,需要借助FormData对象,
  //同时此对象可以添加其他的参数,
  const formData = new FormData()
  option.forEach((file) => {
    console.log(file)
    formData.append('excelFile', file)
  })

  return upload({
    baseURL:'http://localhost',
    url: '/sys/sys_user/upload',
    formData
  })
}

//axios请求
function upload(option: any) {
  return axios.post(option.url, option.formData, {
    headers: {
      'Content-Type': 'multipart/form-data',
    },
    baseURL:option.baseURL
  })
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,关于这个问题,你需要先在你的项目中安装 element-plus 和 axios 这两个库,然后按照以下步骤来实现文件上传: 1. 在组件中导入要使用的库: ``` import { defineComponent } from 'vue' import { ElUpload } from 'element-plus' import axios from 'axios' ``` 2. 创建上传函数,并将 formData 发送至服务器: ``` export default defineComponent({ components: { ElUpload }, methods: { uploadFile(file) { const formData = new FormData() formData.append('file', file.raw) axios.post('/upload', formData, { headers: { 'Content-Type': 'multipart/form-data' } }) .then(response => { console.log(response.data); }) } } }) ``` 3. 在模板中引入上传组件: ``` <template> <el-upload class="upload-demo" :action="uploadFile" list-type="picture" :on-success="onSuccess" :on-change="onChange" :before-upload="beforeUpload" > <el-button size="small" type="primary">点击上传</el-button> </el-upload> </template> ``` 4. 最后,通过 on-success 回调函数来处理服务器返回的上传成功信息: ``` export default defineComponent({ components: { ElUpload }, methods: { uploadFile(file) { const formData = new FormData() formData.append('file', file.raw) axios.post('/upload', formData, { headers: { 'Content-Type': 'multipart/form-data' } }) .then(response => { console.log(response.data); }) }, onSuccess(response, file, fileList) { console.log('上传成功'); console.log(response); console.log(file); console.log(fileList); } } }) ``` 希望这个回答能够帮到你!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值