vue3封装图片上传文件组件

如何使用Vue3框架来封装一个简单而强大的文件上传组件。这个组件将帮助你实现文件的上传功能,并且能够与其他组件进行数据的双向绑定,使你能够轻松地处理上传的文件信息。

  1. 为什么文件上传组件很重要,以及封装这个组件的目的。
  2. 使用Vue3的新语法(<script lang="ts" setup>)来编写组件代码。
  3. 组件的模板结构和基本样式。
  4. 定义组件的属性和状态对象,以及如何实现数据的双向绑定。
  5. 使用一个流行的UI组件库(例如Acro Design)来构建漂亮的上传界面。
  6. 处理文件上传前、上传中和上传后的逻辑。
  7. 通过自定义事件,将上传成功的文件信息传递给父组件。
  8. 在你的项目中使用封装好的文件上传组件,并将文件信息与其他组件进行绑定。

通过这篇教程,你将学会如何使用Vue3框架封装一个简单并且功能强大的文件上传组件。这个组件将为你提供一种方便的方式来上传文件,并且能够与其他组件实现数据的双向绑定。希望这篇教程能帮助你提升Vue3的应用技巧!如果你有任何问题,请随时向我提问。
之前使用vue2封装过图片上传后面vue3更新之后一直没有时间来写博客。现在抽着时间来把vue3的文件上传组件补上。
封装组件一个是方便一个是数据的双向绑定,这一点也是vue的核心,之前vue2使用value然后子组件使用emit(‘input’)方式,或者使用async的方法子组件用emit(‘update:prop’)方法。
现在vue3也有语法糖具体的实现代码


<template>
  <div>
    <a-upload
      v-bind="$attrs"
      :multiple="props.multiple"
      :action="uploadUrl"
      :file-list="state.fileList"
      :headers="state.token"
      :on-before-upload="handleOnBeforeUpload"
      :on-before-remove="handleOnBeforeRemove"
      @error="handleError"
      @change="handleChange"
      @success="handleSuccess"
      image-preview
    >
      <slot />
    </a-upload>
  </div>
</template>

<script lang="ts" setup>
  import { reactive, watch } from 'vue';
  import Message from '@arco-design/web-vue/es/message';
  import { uploadUrl } from '../../api/upload';
  import { getToken } from '../../utils/auth';

  const emit = defineEmits(['update:modelValue', 'handleChange']);

  const props = defineProps({
    modelValue: {
      type: Array,
      default: () => [],
    },
    multiple: {
      type: Boolean,
      default: () => false,
    },
  });

  type FileItem = {
    uid: string;
    status: any;
    file: File;
    percent: number;
    response: any;
    url: string;
    name: string;
  };
  type State = {
    token: { Authorization: string };
    fileList: { status?: string; uid?: string; name?: string; url: string }[];
  };
  const state: State = reactive({
    token: { Authorization: `Bearer  ${getToken()}` },
    fileList: [],
  });

  watch(
    () => props.modelValue,
    (newValue) => {
      state.fileList = [...newValue] as any;
    },
    { immediate: true, deep: true }
  );

  

  const handleOnBeforeRemove = (fileItem: FileItem) => {
    state.fileList = state.fileList.filter((item) => item.url !== fileItem.url);
    emit('update:modelValue', state.fileList);

    return true;
  };

  const handleChange = (fileList: FileItem[], fileItem: FileItem) => {
    if (fileItem?.status === 'done') {
      if (fileItem?.response?.code === 200) {
        Message.success(`${fileItem.name} 上传成功`);
        state.fileList = fileList.map((item): any => {
          if (item.status === 'done' && item.percent === 1) {
            return {
              url: item?.response?.data?.url || item.url,
              name: item?.response?.data?.name || item.name,
              uid: item?.uid || Math.random() * 10000,
            };
          }
          return false;
        });
        emit('handleChange', fileItem);
        emit('update:modelValue', state.fileList);
      } else if (fileItem?.response?.msg) {
        Message.error(fileItem?.response?.msg);
      }
    } else if (fileItem.status === 'error') {
      Message.error(`${fileItem.name} 上传失败`);
    }
  };
  const handleSuccess = (fileItem: FileItem) => {};
</script>

在这里插入图片描述

这就是实际项目中用到的一个文件上传组件。这个用的acro-design组件封装的原理都一样使用ui库只是便捷我们的开发。

Logo

前往低代码交流专区

更多推荐