AntdV Upload组件customRequest该如何自定义上传方法

发布时间:2021-12-24 20:30:35 作者:柒染
来源:亿速云 阅读:993
# AntdV Upload组件customRequest该如何自定义上传方法

## 一、Upload组件基础回顾

Ant Design Vue(简称AntdV)的Upload组件是前端开发中常用的文件上传控件,它提供了多种上传模式和丰富的交互功能。在基础用法中,我们通常这样使用:

```vue
<template>
  <a-upload
    name="file"
    action="/api/upload"
    @change="handleChange"
  >
    <a-button>点击上传</a-button>
  </a-upload>
</template>

这种标准用法虽然简单,但在实际业务场景中往往需要更复杂的控制,这时就需要用到customRequest属性。

二、为什么需要customRequest

标准上传方式存在几个局限性:

  1. 无法完全控制上传过程:标准方式依赖浏览器默认的XMLHttpRequest行为
  2. 难以添加自定义headers:比如需要携带Authorization token时
  3. 特殊文件处理需求:如分片上传、断点续传、文件预处理等
  4. 对接非标准后端接口:当后端API设计不符合RESTful规范时

三、customRequest核心机制

customRequest需要接收一个函数,该函数会覆盖组件默认的上传行为。函数参数包含以下关键属性:

function customRequest({
  action,        // 上传地址
  file,          // 文件对象
  filename,      // 文件名
  data,          // 额外数据
  headers,       // 请求头
  withCredentials, // 跨域凭证
  onProgress,    // 进度回调
  onSuccess,     // 成功回调
  onError,       // 失败回调
}) {
  // 自定义实现
}

四、完整实现方案

4.1 基础实现示例

<template>
  <a-upload
    :customRequest="customUpload"
  >
    <a-button>自定义上传</a-button>
  </a-upload>
</template>

<script>
export default {
  methods: {
    async customUpload({
      file,
      onProgress,
      onSuccess,
      onError,
    }) {
      const formData = new FormData()
      formData.append('file', file)
      
      try {
        const res = await axios.post('/api/upload', formData, {
          headers: {
            'Content-Type': 'multipart/form-data',
            'Authorization': `Bearer ${token}`
          },
          onUploadProgress: (e) => {
            if (e.lengthComputable) {
              onProgress({ percent: e.loaded / e.total * 100 }, file)
            }
          }
        })
        onSuccess(res.data, file)
      } catch (err) {
        onError(err)
      }
    }
  }
}
</script>

4.2 高级功能实现

分片上传实现

async function chunkedUpload({ file, onProgress }) {
  const CHUNK_SIZE = 5 * 1024 * 1024 // 5MB
  const chunks = Math.ceil(file.size / CHUNK_SIZE)
  let uploaded = 0
  
  for (let i = 0; i < chunks; i++) {
    const chunk = file.slice(
      i * CHUNK_SIZE,
      Math.min((i + 1) * CHUNK_SIZE, file.size)
    )
    
    await uploadChunk(chunk, i).then(() => {
      uploaded++
      onProgress({ percent: uploaded / chunks * 100 })
    })
  }
}

文件预处理示例

function customUpload({ file, beforeUpload }) {
  return new Promise((resolve) => {
    const reader = new FileReader()
    reader.onload = (e) => {
      // 对文件内容进行预处理
      const processed = processFile(e.target.result)
      resolve(processed)
    }
    reader.readAsDataURL(file)
  }).then(processedFile => {
    // 上传处理后的文件
  })
}

五、常见问题解决方案

5.1 进度条不更新

确保正确计算并调用onProgress

onProgress({ percent: loaded / total * 100 }, file)

5.2 上传后列表不更新

需要手动调用onSuccessonError

// 成功时
onSuccess(responseData, file)

// 失败时
onError(new Error('上传失败'), null, file)

5.3 跨域问题处理

headers: {
  'Access-Control-Allow-Origin': '*',
  // 其他必要headers
},
withCredentials: true

六、最佳实践建议

  1. 错误处理:实现完整的错误捕获和用户提示
  2. 取消功能:结合AbortController实现上传取消
  3. 类型校验:在上传前验证文件类型和大小
  4. 性能优化:大文件使用分片上传
  5. 安全考虑:对敏感文件进行前端加密

七、完整示例代码

<template>
  <a-upload
    :multiple="true"
    :customRequest="handleUpload"
    @change="handleChange"
    :showUploadList="true"
  >
    <a-button> <upload-outlined /> 选择文件 </a-button>
  </a-upload>
</template>

<script>
import axios from 'axios'
import { UploadOutlined } from '@ant-design/icons-vue'

export default {
  components: { UploadOutlined },
  methods: {
    async handleUpload({ file, onProgress, onSuccess, onError }) {
      // 1. 文件校验
      if (file.size > 50 * 1024 * 1024) {
        return onError(new Error('文件大小不能超过50MB'))
      }
      
      // 2. 准备上传数据
      const formData = new FormData()
      formData.append('file', file)
      formData.append('timestamp', Date.now())
      
      try {
        // 3. 执行上传
        const res = await axios.post('/api/v2/upload', formData, {
          headers: {
            'X-Auth-Token': localStorage.getItem('token'),
            'Content-Type': 'multipart/form-data'
          },
          onUploadProgress: e => {
            if (e.lengthComputable) {
              onProgress({ percent: (e.loaded / e.total) * 100 }, file)
            }
          }
        })
        
        // 4. 处理响应
        if (res.data.code === 200) {
          onSuccess(res.data, file)
        } else {
          onError(new Error(res.data.message), null, file)
        }
      } catch (err) {
        // 5. 错误处理
        onError(err, null, file)
        this.$message.error('上传失败: ' + err.message)
      }
    },
    
    handleChange(info) {
      if (info.file.status === 'done') {
        this.$message.success(`${info.file.name} 上传成功`)
      }
    }
  }
}
</script>

结语

通过customRequest的自定义上传功能,开发者可以完全掌控文件上传的各个环节,实现各种复杂的业务需求。掌握这一技术点,将使你在处理文件上传类需求时游刃有余。 “`

推荐阅读:
  1. 怎么在antd组件中使用Upload实现自己上传
  2. antd Upload 文件上传的步骤

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

上一篇:设置vue动态浏览器标题的方法有哪些

下一篇:linux中如何删除用户组

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》