vue3 ant-vue form表单里的upload组件封装

这篇博客详细介绍了如何在Vue项目中利用Ant Design Vue组件库实现图片上传功能,包括设置上传限制(如文件类型、大小)、上传状态显示(如加载中、上传成功、上传失败)以及回调函数的使用,帮助开发者更好地理解和实现在前端进行图片上传的逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<template>
  <a-upload
    v-model:file-list="fileList"
    name="file"
    list-type="picture-card"
    class="avatar-uploader"
    :show-upload-list="false"
    :action="action"
    :before-upload="beforeUpload"
    @change="handleChange"
    v-bind="$attrs"
  >
    <a-image
      :width="48"
      :height="48"
      v-if="value" :src="value"
    />
    <div v-else>
      <loading-outlined v-if="loading"></loading-outlined>
      <plus-outlined v-else></plus-outlined>
    </div>
  </a-upload>
</template>
<script>
import { defineComponent, ref, watch } from 'vue';
import { PlusOutlined, LoadingOutlined } from '@ant-design/icons-vue';
import { message } from 'ant-design-vue';

export default defineComponent({
  components: {
    LoadingOutlined,
    PlusOutlined,
  },
  props:['value'],
  inheritAttrs: false,
  emits:['update:value'],
  setup(props,{emit}) {
    const fileList = ref([]);
    const loading = ref(false);
    const imageUrl = ref();
    const action = ref(`http://192.168.2.2:8080/uplaodurl`);
    const handleChange = info => {
      if (info.file.status === 'uploading') {
        loading.value = true;
        return;
      }

      if (info.file.status === 'done') {
          loading.value = false;
        if(info.file.response.code==0){
          emit('change',info)
          imageUrl.value = info.file.response.data;
        }
      }

      if (info.file.status === 'error') {
        loading.value = false;
        message.error('upload error');
      }
    };

    const beforeUpload = file => {
      const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';

      if (!isJpgOrPng) {
        message.error('You can only upload JPG file!');
      }

      const isLt2M = file.size / 1024 / 1024 < 2;

      if (!isLt2M) {
        message.error('Image must smaller than 2MB!');
      }

      return isJpgOrPng && isLt2M;
    };
    watch(imageUrl, (newValue, oldValue) => {
      emit('update:value', newValue)
    });
    return {
      fileList,
      loading,
      imageUrl,
      action,
      handleChange,
      beforeUpload,
    };
  },
});
</script>
<style>
.avatar-uploader > .ant-upload {
  width: 64px;
  height: 64px;
}
.ant-upload-select-picture-card i {
  font-size: 32px;
  color: #999;
}

.ant-upload-select-picture-card .ant-upload-text {
  margin-top: 8px;
  color: #666;
}
</style>

<think>嗯,用户想封装一个基于ant-design-vueUpload组件的自定义组件。首先,我需要回忆一下ant-design-vueUpload组件的使用方法,特别是自定义上传的部分。记得文档提到过,当需要自定义上传逻辑时,应该使用customRequest属性。这样原有的上传行为会被覆盖,用户需要自己处理上传过程。 首先,用户可能需要一个示例代码结构。我应该先确定如何创建一个Vue组件,引入a-upload组件,然后绑定必要的属性和事件。比如,设置disabled来控制是否禁用,action虽然可能不需要,但可能需要占位符。然后是customRequest方法,这需要处理文件的上传,比如用axios或者fetch。需要生成一个示例的customRequest函数,包括上传进度、成功和失败的处理。 然后,用户可能想控制文件列表,所以需要用到v-model:file-list来绑定文件列表,并且在组件内部处理文件的添加、删除等操作。可能需要用到beforeUpload钩子来限制文件类型和大小,比如图片类型和2MB的限制。 接下来,用户可能需要展示上传进度,所以需要在上传过程中更新file对象的percent属性,这样进度条才会正确显示。同时,上传成功或失败后要更新文件的状态,比如status属性设为done或error,并设置对应的response或error信息。 还有,用户可能希望这个自定义组件能和表单组件配合使用,所以需要确保file-list的双向绑定是正确的,并且在删除文件时触发change事件,让父组件能更新状态。 另外,要考虑如何暴露组件的属性和事件,比如允许父组件传递disabled属性,或者处理上传失败时的错误提示。可能需要使用Ant Design的message组件来显示错误信息。 现在,需要检查是否有遗漏的步骤。比如,是否需要处理多文件上传,是否需要支持拖拽上传,或者预览功能。不过根据用户的问题,可能暂时不需要这些高级功能,但可以在示例中提及可能的扩展点。 最后,总结一下步骤:创建Vue组件,引入a-upload,处理customRequest,管理file-list,添加beforeUpload验证,处理上传状态和进度,集成到表单中。然后给出示例代码,并附上相关的问题供用户参考。</think>### 基于 ant-design-vueUpload 自定义组件封装指南 #### 一、核心实现步骤 1. **组件基础结构** ```vue <template> <a-upload v-model:file-list="fileList" :disabled="disabled" :custom-request="customRequest" :before-upload="beforeUpload" @remove="handleRemove" > <!-- 自定义上传按钮 --> </a-upload> </template> ``` 2. **自定义上传实现** ```typescript const customRequest = async (options: UploadRequestOption) => { const { file, onProgress, onSuccess, onError } = options; const formData = new FormData(); formData.append(&#39;file&#39;, file as RcFile); try { const res = await axios.post(&#39;your_api_url&#39;, formData, { onUploadProgress: (progressEvent) => { const percent = Math.round( (progressEvent.loaded * 100) / progressEvent.total ); onProgress({ percent }, file); } }); onSuccess(res.data, file); } catch (error) { onError(error); message.error(&#39;上传失败&#39;); } }; ``` 3. **文件校验逻辑** ```typescript const beforeUpload = (file: File) => { const isImage = file.type.startsWith(&#39;image/&#39;); if (!isImage) message.error(&#39;仅支持图片格式&#39;); const isLt2M = file.size / 1024 / 1024 < 2; if (!isLt2M) message.error(&#39;文件不能超过2MB&#39;); return isImage && isLt2M; }; ``` #### 二、关键特性说明 1. **文件列表控制** 通过`v-model:file-list`实现双向绑定,需手动维护文件状态: - 上传成功时设置`status: &#39;done&#39;` - 失败时设置`status: &#39;error&#39;` - 进度更新`percent`字段[^2] 2. **表单集成** 需配合`<a-form-item>`使用,通过`name`属性绑定表单字段: ```vue <a-form-item name="attachments"> <custom-upload /> </a-form-item> ``` #### 三、完整组件示例 ```vue <script setup lang="ts"> import { message } from &#39;ant-design-vue&#39;; interface Props { disabled?: boolean; } defineProps<Props>(); const fileList = ref<UploadFile[]>([]); const handleRemove = (file: UploadFile) => { const index = fileList.value.indexOf(file); fileList.value.splice(index, 1); }; </script> <template> <a-upload v-model:file-list="fileList" list-type="picture-card" :disabled="disabled" :custom-request="customRequest" :before-upload="beforeUpload" @remove="handleRemove" > <div v-if="fileList.length < 5"> <plus-outlined /> <div>上传文件</div> </div> </a-upload> </template> ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值