element upload文件上传第二次上传失败的解决方法

文章介绍了如何在Vue的el-upload组件中,设置文件上传的限制数量为2,并解决上传后默认保留最后一个文件的问题。通过before-upload钩子判断文件类型并提供错误提示,changeFiles方法处理文件列表。
<template>
  <div>
    <!-- 解决思路:设置limit可以上传2个文件,但上传2个文件成功后,默认把第一个文件去掉,只保留最后上传的文件 -->
    <el-upload action="#" :auto-upload="true" :limit="2" :on-change="changeFiles" :before-upload="beforeUpload" :on-success="uploadSuccess" :on-error="uploadError" :on-remove="removeFilePath" :on-exceed="onExceed" ref="myUpload">
      <el-button size="small" slot="trigger">上传文件</el-button>
      <div slot="tip" class="el-upload__tip" v-if="showFileTips">
        {{
          "只支持上传" + getAcceptFileTips + "文件"
        }}
      </div>
    </el-upload>
  </div>
</template>

<script>
export default {
  name: 'myUploadCompoent',
  data() {
    return {}
  },
  model: {
    prop: 'fileInfo',
    event: 'change'
  },
  props: {
    fileInfo: Object,
    customFileTips: { type: String, default: '' },
    showFileTips: { type: Boolean, default: true },
    disabled: {
      type: Boolean,
      default: false
    },
    //接收的文件类型
    acceptFileArr: {
      type: Array,
      default: function () {
        return ['.txt', '.doc']
      }
    },
  },
  computed: {
    getAcceptFileTips() {
      return this.acceptFileArr.join(' ')
    }
  },
  mounted() {},
  methods: {
    beforeUpload(res) {
      // 获取当前上传文件的类型
      if (this.acceptFileArr?.length > 0 && res?.name) {
        let nowFileType = ''
        try {
          nowFileType = res.name.substring(res.name.lastIndexOf('.'))
        } catch (error) {
          nowFileType = ''
        }
        if (nowFileType && this.acceptFileArr.indexOf(nowFileType) === -1) {
          //给出提示:请上传正确格式的文件
          return false
        }
      }
      return true
    },
    changeFiles(file, fileList) {
      //解决思路:设置limit可以上传2个文件,但上传2个文件成功后,默认把第一个文件去掉,只保留最后上传的文件
      if (fileList.length > 1) {
        fileList.shift()
      }
    },
    uploadError() {
      // 文件上传失败
    },
    uploadSuccess(res, file, fileList) {
      if (res?.data?.path) {
        this.fileInfo.path = res.data.path
        this.$emit('fileChange', this.fileInfo)
      }
    },
    onExceed(res, file) {},
  }
}
</script>

<style lang="less" scoped></style>

在使用 `element-plus` 的 `el-upload` 组件时,如果尝试上传相同文件(例如相同的文件名和内容),第二次及之后的上传可能会失效。这通常是因为浏览器缓存机制或组件内部对重复文件的处理逻辑导致的。 ### 解决方法 1. **修改文件唯一标识** 通过为每次上传的文件生成唯一的标识符(如 `uid`),可以绕过组件对重复文件的判断机制。这可以通过结合 `before-upload` 钩子函数来实现: ```vue <template> <el-upload :action="uploadUrl" :before-upload="handleBeforeUpload" :on-success="handleSuccess" :on-error="handleError" > <el-button>选择文件</el-button> </el-upload> </template> <script setup> import { genFileId } from 'element-plus'; const handleBeforeUpload = (file) => { // 为文件添加唯一标识 file.uid = genFileId(); return true; // 返回 true 表示允许上传 }; const handleSuccess = (response, file, fileList) => { console.log('上传成功:', response); }; const handleError = (error, file, fileList) => { console.error('上传失败:', error); }; </script> ``` 2. **清除文件列表并重新触发上传** 如果需要多次上传相同文件,可以在每次上传前手动清空文件列表,并重新设置文件状态: ```vue <template> <el-upload ref="uploadRef" :action="uploadUrl" :auto-upload="false" :file-list="fileList" v-model:file-list="fileList" > <el-button @click="uploadFile">上传文件</el-button> </el-upload> </template> <script setup> import { ref } from 'vue'; import { genFileId } from 'element-plus'; const uploadRef = ref(); const fileList = ref([]); const uploadFile = () => { // 清空现有文件列表 uploadRef.value.clearFiles(); // 模拟选择新文件 const newFile = { name: 'test.jpg', size: 1024, type: 'image/jpeg', uid: genFileId(), // 生成唯一标识 }; // 手动添加文件到上传队列 uploadRef.value.handleStart(newFile); // 提交上传 uploadRef.value.submit(); }; </script> ``` 3. **使用 `v-model:file-list` 而非 `:file-list`** 在某些情况下,直接使用 `:file-list` 可能会导致文件状态无法正确更新。改用 `v-model:file-list` 可以确保双向绑定文件列表的状态,避免因数据不同步导致的问题。 ```vue <el-upload v-model:file-list="fileList" :action="uploadUrl" :limit="1" :on-exceed="handleExceed" :auto-upload="false" > <el-button>上传文件</el-button> </el-upload> ``` 4. **自定义 `http-request` 方法** 通过自定义 `http-request`,可以完全控制文件上传过程,避免依赖默认行为可能带来的问题: ```vue <template> <el-upload :http-request="customUpload" :auto-upload="false" :file-list="fileList" v-model:file-list="fileList" > <el-button>上传文件</el-button> </el-upload> </template> <script setup> import { ref } from 'vue'; const fileList = ref([]); const uploadUrl = 'https://your.upload.url'; // 替换为实际上传地址 const customUpload = async (params) => { const { file } = params; const formData = new FormData(); formData.append('file', file); try { const response = await fetch(uploadUrl, { method: 'POST', body: formData, }); if (response.ok) { console.log('上传成功'); } else { console.error('上传失败'); } } catch (error) { console.error('网络错误:', error); } }; </script> ``` ###
在使用 Element UI 的上传组件(`el-upload`)时,手动调用上传实例的方法是一种常见的需求,尤其是在需要控制上传流程的场景中。然而,在第二次上传时出现错误,可能是由以下几个原因造成的: ### 1. 文件状态未重置 Element UI 的 `el-upload` 组件在首次上传后,会将文件列表标记为“已上传”或“成功”状态。如果未对文件状态进行重置,再次调用上传方法时可能会因为状态冲突而失败。可以通过清空文件列表或修改文件状态来解决此问题。 ```javascript this.$refs.upload.clearFiles(); // 清除已上传的文件列表 ``` ### 2. 请求参数未更新 在某些情况下,上传请求所依赖的参数可能没有更新,导致服务端拒绝重复请求。例如,上传路径、请求头或表单数据(如 `FormData`)中的字段未发生变化,服务器可能将其识别为重复提交并返回错误。确保每次上传前更新必要的参数,尤其是时间戳或唯一标识符。 ```javascript const formData = new FormData(); formData.append('file', file); formData.append('timestamp', new Date().getTime()); // 添加时间戳避免重复 ``` ### 3. 实例方法调用时机不当 手动调用上传方法时,若未正确等待上一次上传完成或未处理异步逻辑,可能导致上传操作冲突。建议在确认上一次上传完成后,再触发新的上传行为,可以借助 Promise 或 async/await 来管理流程。 ```javascript async function handleUpload(file) { await this.$refs.upload.submit(); // 等待上次上传完成 this.$refs.upload.clearFiles(); // 清除文件列表 this.$refs.upload.submit(); // 再次上传 } ``` ### 4. 文件对象未重新赋值 在手动上传时,如果没有重新设置文件对象,可能会导致组件尝试上传一个已经上传过的文件对象,从而引发错误。确保每次上传都传入一个新的文件对象。 ```javascript const newFile = new File([file.raw], file.name); // 创建新文件对象 this.$refs.upload.handleStart(newFile); // 启动上传 ``` ### 5. 组件配置问题 检查 `el-upload` 的相关配置是否支持多次上传,例如 `limit` 属性限制了最大上传数量,或者 `before-upload` 钩子函数中存在阻止重复上传的逻辑。 ```html <el-upload ref="upload" action="/api/upload" :auto-upload="false" :limit="1" :on-exceed="handleExceed" > <el-button>选择文件</el-button> <el-button @click="submitUpload">上传</el-button> </el-upload> ``` 通过以上方式,可以有效排查和解决 Element UI 手动上传组件在第二次上传时出错的问题。若问题仍然存在,建议检查浏览器控制台日志和网络请求详情,以获取更具体的错误信息[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值