Skip to content

UIUpload

UIUpload

UIUpload is a component that provides an interface for users to upload files. It supports features like drag-and-drop uploading, file previews, automatic file validation, and multiple file selection.

<template>
<UIUpload
v-model:fileList="fileList"
action="/api/upload"
:maxCount="5"
:beforeUpload="beforeUpload"
@success="handleSuccess"
>
<UIButton type="primary" icon="upload">Upload Files</UIButton>
</UIUpload>
</template>
<script setup>
import { ref } from 'vue';
const fileList = ref([]);
const beforeUpload = (file) => {
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isJpgOrPng) {
// Show error notification
return false;
}
if (!isLt2M) {
// Show error notification
return false;
}
return true;
};
const handleSuccess = (response, file, fileList) => {
console.log('Upload success:', response);
};
</script>

Props

  • fileList (Array): List of files to upload or that have been uploaded
  • action (string): The URL to which the files will be uploaded
  • headers (object): Additional request headers to send
  • multiple (boolean, default: false): Whether to allow multiple file selection
  • directory (boolean, default: false): Whether to allow folder uploads
  • accept (string): File types that can be accepted (e.g., ‘.jpg,.png’)
  • maxCount (number): Maximum number of files that can be uploaded
  • maxSize (number): Maximum file size in bytes
  • disabled (boolean, default: false): Whether the upload is disabled
  • listType (‘text’ | ‘picture’ | ‘picture-card’, default: ‘text’): Type of file list
  • showUploadList (boolean, default: true): Whether to show the uploaded file list
  • drag (boolean, default: false): Whether to enable drag and drop mode
  • autoUpload (boolean, default: true): Whether to automatically upload files when selected
  • withCredentials (boolean, default: false): Whether to send cookies
  • beforeUpload (Function(file, fileList) => boolean | Promise): Hook before uploading
  • customRequest (Function): Custom implementation for the upload request
  • data (object | Function): Additional data sent with upload request
  • name (string, default: ‘file’): Name of the file parameter sent to the server

Events

  • update:fileList (fileList: Array): Emitted when the file list changes
  • change ({ file, fileList, event }): Emitted when uploaded files change
  • success (response, file, fileList): Emitted when upload succeeds
  • error (error, file, fileList): Emitted when upload fails
  • progress (event, file, fileList): Emitted during upload progress
  • preview (file): Emitted when a file is clicked for preview
  • remove (file): Emitted when a file is removed from the list
  • exceed (files, fileList): Emitted when the number of files exceeds maxCount
  • drop (event): Emitted when files are dropped in drag area

Slots

  • default: Content for the upload trigger button/area
  • tip: Content for the upload tip displayed below the upload control
  • drag: Custom drag area content
  • file (scoped slot with { file, fileList }): Custom file list item content

Usage Examples

  1. Basic Upload:
<template>
<UIUpload
v-model:fileList="fileList"
action="/api/upload"
@change="handleChange"
>
<UIButton icon="upload">Click to Upload</UIButton>
</UIUpload>
</template>
<script setup>
import { ref } from 'vue';
const fileList = ref([]);
const handleChange = ({ file, fileList }) => {
console.log('Upload status:', file.status);
};
</script>
  1. Drag and Drop Upload:
<template>
<UIUpload
v-model:fileList="fileList"
action="/api/upload"
:drag="true"
multiple
>
<div class="upload-drag-area">
<p><UIIcon name="upload" :size="48" /></p>
<p>Drag files here or <a>click to upload</a></p>
<p class="upload-hint">Support for single or bulk upload</p>
</div>
</UIUpload>
</template>
  1. Image List Upload:
<template>
<UIUpload
v-model:fileList="fileList"
action="/api/upload"
listType="picture-card"
:maxCount="5"
accept=".jpg,.jpeg,.png,.gif"
>
<div v-if="fileList.length < 5">
<UIIcon name="plus" />
<div style="margin-top: 8px">Upload</div>
</div>
</UIUpload>
</template>
  1. Manual Upload with Validation:
<template>
<UIUpload
v-model:fileList="fileList"
action="/api/upload"
:autoUpload="false"
:beforeUpload="beforeUpload"
multiple
>
<UIButton icon="select">Select Files</UIButton>
<template #tip>
<div class="upload-tip">
JPG/PNG files less than 2MB
</div>
</template>
</UIUpload>
<div style="margin-top: 16px">
<UIButton
type="primary"
@click="submitUpload"
:disabled="!fileList.length"
>
Start Upload
</UIButton>
</div>
</template>
<script setup>
import { ref } from 'vue';
const fileList = ref([]);
const uploadRef = ref(null);
const beforeUpload = (file) => {
const isImage = /\.(jpg|jpeg|png)$/i.test(file.name);
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isImage) {
alert('You can only upload JPG or PNG files!');
return false;
}
if (!isLt2M) {
alert('Image must be smaller than 2MB!');
return false;
}
return true;
};
const submitUpload = () => {
uploadRef.value.submit();
};
</script>
  1. Custom File List:
<template>
<UIUpload
v-model:fileList="fileList"
action="/api/upload"
:showUploadList="false"
@change="handleChange"
>
<UIButton icon="upload">Upload Files</UIButton>
</UIUpload>
<div class="custom-file-list">
<div v-for="(file, index) in fileList" :key="index" class="file-item">
<div class="file-info">
<UIIcon :name="getFileIcon(file)" />
<span class="file-name">{{ file.name }}</span>
</div>
<div class="file-status">
<template v-if="file.status === 'uploading'">
<UIProgress :percent="file.percent" />
</template>
<template v-else-if="file.status === 'done'">
<UIIcon name="check-circle" style="color: green;" />
</template>
<template v-else-if="file.status === 'error'">
<UIIcon name="close-circle" style="color: red;" />
</template>
<UIButton
type="text"
icon="delete"
@click="removeFile(file)"
style="margin-left: 8px;"
/>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue';
const fileList = ref([]);
const getFileIcon = (file) => {
const extension = file.name.split('.').pop().toLowerCase();
if (['jpg', 'jpeg', 'png', 'gif'].includes(extension)) {
return 'file-image';
} else if (['doc', 'docx'].includes(extension)) {
return 'file-word';
} else if (['xls', 'xlsx'].includes(extension)) {
return 'file-excel';
} else if (['pdf'].includes(extension)) {
return 'file-pdf';
}
return 'file';
};
const handleChange = ({ file, fileList }) => {
// Update file list
};
const removeFile = (file) => {
fileList.value = fileList.value.filter(item => item.uid !== file.uid);
};
</script>

Best Practices

  1. File Validation:

    • Validate file types before upload
    • Set appropriate file size limits
    • Communicate requirements clearly
    • Handle validation errors gracefully
  2. User Experience:

    • Show upload progress indicators
    • Provide clear success/error feedback
    • Allow previewing uploaded files when appropriate
    • Use drag-and-drop for better usability
    • Consider multiple file selection needs
  3. Error Handling:

    • Provide meaningful error messages
    • Handle network failures gracefully
    • Allow retrying failed uploads
    • Consider offline scenarios
  4. Performance:

    • Consider file compression for large uploads
    • Implement chunked uploads for very large files
    • Optimize preview generation
    • Cache uploaded files when appropriate