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 uploadedaction(string): The URL to which the files will be uploadedheaders(object): Additional request headers to sendmultiple(boolean, default: false): Whether to allow multiple file selectiondirectory(boolean, default: false): Whether to allow folder uploadsaccept(string): File types that can be accepted (e.g., ‘.jpg,.png’)maxCount(number): Maximum number of files that can be uploadedmaxSize(number): Maximum file size in bytesdisabled(boolean, default: false): Whether the upload is disabledlistType(‘text’ | ‘picture’ | ‘picture-card’, default: ‘text’): Type of file listshowUploadList(boolean, default: true): Whether to show the uploaded file listdrag(boolean, default: false): Whether to enable drag and drop modeautoUpload(boolean, default: true): Whether to automatically upload files when selectedwithCredentials(boolean, default: false): Whether to send cookiesbeforeUpload(Function(file, fileList) => boolean | Promise): Hook before uploadingcustomRequest(Function): Custom implementation for the upload requestdata(object | Function): Additional data sent with upload requestname(string, default: ‘file’): Name of the file parameter sent to the server
Events
update:fileList(fileList: Array): Emitted when the file list changeschange({ file, fileList, event }): Emitted when uploaded files changesuccess(response, file, fileList): Emitted when upload succeedserror(error, file, fileList): Emitted when upload failsprogress(event, file, fileList): Emitted during upload progresspreview(file): Emitted when a file is clicked for previewremove(file): Emitted when a file is removed from the listexceed(files, fileList): Emitted when the number of files exceeds maxCountdrop(event): Emitted when files are dropped in drag area
Slots
default: Content for the upload trigger button/areatip: Content for the upload tip displayed below the upload controldrag: Custom drag area contentfile(scoped slot with{ file, fileList }): Custom file list item content
Usage Examples
- 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>- 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>- 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>- 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>- 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
-
File Validation:
- Validate file types before upload
- Set appropriate file size limits
- Communicate requirements clearly
- Handle validation errors gracefully
-
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
-
Error Handling:
- Provide meaningful error messages
- Handle network failures gracefully
- Allow retrying failed uploads
- Consider offline scenarios
-
Performance:
- Consider file compression for large uploads
- Implement chunked uploads for very large files
- Optimize preview generation
- Cache uploaded files when appropriate