Skip to content

Upload Component ​

This component is used for file upload scenarios, supporting the upload of images, videos, and various other file types

📌 Platform Differences ​

APP(vue)H5WeChat Mini ProgramAlipay Mini Program
✔✔✔✔

🏯 Basic Usage ​

html
<!-- Global usage -->
<hy-upload :fileList="list"></hy-upload>

Basic Upload ​

html
<template>
    <hy-upload :fileList="list" @afterRead="afterRead"></hy-upload>
</template>
ts
import { ref } from 'vue';
import type { FileVo } from '@/package/components/hy-upload/typing';

const list = ref<FileVo[]>([]);

const afterRead = (event: any) => {
    const file = event.file;
    list.value.push({
        status: 'loading',
        message: 'Uploading',
        url: file.url,
        schedule: 0,
    });
    // Simulate upload progress
    let progress = 0;
    const timer = setInterval(() => {
        progress += 10;
        list.value[0].schedule = progress;
        if (progress >= 100) {
            clearInterval(timer);
            list.value[0].status = 'success';
            list.value[0].message = 'Upload succeeded';
        }
    }, 200);
};

Limiting Upload Count ​

Use maxCount to set the maximum number of uploads. The default is 52.

html
<hy-upload :fileList="list" :maxCount="3" @afterRead="afterRead"></hy-upload>

Multiple Image Upload ​

Set multiple to enable multi-select mode. Some Android devices do not support it.

html
<hy-upload :fileList="list" multiple @afterRead="afterRead"></hy-upload>
ts
import { ref } from 'vue';
import type { FileVo } from '@/package/components/hy-upload/typing';
import { isArray } from '@/package';

const list = ref<FileVo[]>([]);

const afterRead = (event: any) => {
    const files = event.file;
    if (isArray(files)) {
        files.forEach((item) => {
            list.value.push({
                status: 'loading',
                message: 'Uploading',
                url: item.url,
                schedule: 0,
            });
            // Simulate uploading a single file
            const index = list.value.findIndex((v) => v.url === item.url);
            let progress = 0;
            const timer = setInterval(() => {
                progress += 10;
                list.value[index].schedule = progress;
                if (progress >= 100) {
                    clearInterval(timer);
                    list.value[index].status = 'success';
                    list.value[index].message = 'Upload succeeded';
                }
            }, 200);
        });
    }
};

Limiting File Size ​

Use maxSize to set the maximum size of a single file, in bytes (B).

html
<template>
    <hy-upload
        :fileList="list"
        :maxSize="500000"
        @afterRead="afterRead"
        @oversize="onOversize"
    ></hy-upload>
</template>

<script setup lang="ts">
    import { ref } from 'vue';
    import type { FileVo } from '@/package/components/hy-upload/typing';

    const list = ref<FileVo[]>([]);

    const afterRead = (event) => {
        // Handle upload logic
    };

    const onOversize = () => {
        uni.showToast({
            title: 'Image exceeds the 500KB limit',
            icon: 'none',
        });
    };
</script>

Uploading Videos ​

Set accept="video" to restrict uploads to video files only.

html
<template>
    <hy-upload :fileList="list" accept="video" :maxDuration="30" @afterRead="afterRead"></hy-upload>
</template>

<script setup lang="ts">
    import { ref } from 'vue';
    import type { FileVo } from '@/package/components/hy-upload/typing';

    const list = ref<FileVo[]>([]);

    const afterRead = (event) => {
        const file = event.file as FileVo;
        list.value.push({
            type: 'video',
            status: 'success',
            message: 'Upload succeeded',
            url: file.url,
        });
    };
</script>

Custom Upload Button ​

Use the default slot to customize the upload button style.

html
<template>
    <hy-upload :fileList="list" @afterRead="afterRead">
        <view class="custom-upload-btn">
            <hy-icon name="plus" color="#999" size="32"></hy-icon>
            <text class="custom-upload-text">Click to upload</text>
        </view>
    </hy-upload>
</template>

<style scoped lang="scss">
    .custom-upload-btn {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        width: 160rpx;
        height: 160rpx;
        border: 2rpx dashed #d9d9d9;
        border-radius: 12rpx;

        .custom-upload-text {
            font-size: 24rpx;
            color: #999;
            margin-top: 8rpx;
        }
    }
</style>

Custom Trigger Area ​

Use the trigger slot to customize the area that triggers the upload.

html
<template>
    <hy-upload :fileList="list" @afterRead="afterRead">
        <template #trigger>
            <view class="custom-trigger">
                <hy-icon name="upload" color="#2979ff" size="48"></hy-icon>
                <text class="custom-trigger-text">Drag or click to upload</text>
            </view>
        </template>
    </hy-upload>
</template>

<style scoped lang="scss">
    .custom-trigger {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        width: 100%;
        height: 200rpx;
        border: 2rpx dashed #2979ff;
        border-radius: 12rpx;
        background: rgba(41, 121, 255, 0.05);

        .custom-trigger-text {
            font-size: 28rpx;
            color: #2979ff;
            margin-top: 12rpx;
        }
    }
</style>

Disabled State ​

Set disabled to disable the upload functionality.

html
<template>
    <hy-upload :fileList="list" disabled>
        <view class="disabled-btn">
            <hy-icon name="lock" color="#ccc" size="24"></hy-icon>
            <text class="disabled-text">Upload disabled</text>
        </view>
    </hy-upload>
</template>

Hiding the Delete Button ​

Set deletable="false" to hide the delete button.

html
<hy-upload :fileList="list" :deletable="false" @afterRead="afterRead"></hy-upload>

Custom Size ​

Customize the size of the upload area via width and height.

html
<hy-upload
    :fileList="list"
    :width="120"
    :height="120"
    upload-text="Large size"
    @afterRead="afterRead"
></hy-upload>

Upload Failed State ​

Set status="failed" to display the upload failed state.

html
<template>
    <hy-upload :fileList="list"></hy-upload>
</template>

<script setup lang="ts">
    import { ref } from 'vue';
    import type { FileVo } from '@/package/components/hy-upload/typing';

    const list = ref<FileVo[]>([
        {
            status: 'failed',
            message: 'Upload failed',
            url: '',
        },
    ]);
</script>

Image Crop Mode ​

Use imageMode to set the crop mode of the preview image, consistent with the mode property of the image component.

html
<hy-upload :fileList="list" imageMode="aspectFit"></hy-upload>

Controlling Preview ​

Use previewFullImage to control whether the fullscreen preview feature is displayed.

html
<hy-upload :fileList="list" :previewFullImage="false"></hy-upload>

Selection Mode ​

Use capture to set the capture mode for images or videos.

html
<!-- Select from album only -->
<hy-upload :fileList="list" :capture="['album']"></hy-upload>

<!-- Capture with camera only -->
<hy-upload :fileList="list" :capture="['camera']"></hy-upload>

<!-- Support both album and camera -->
<hy-upload :fileList="list" :capture="['album', 'camera']"></hy-upload>

Original/Compressed Images ​

Use sizeType to control the size type of the selected images.

html
<!-- Original images only -->
<hy-upload :fileList="list" :sizeType="['original']"></hy-upload>

<!-- Compressed images only -->
<hy-upload :fileList="list" :sizeType="['compressed']"></hy-upload>

<!-- Support both original and compressed images -->
<hy-upload :fileList="list" :sizeType="['original', 'compressed']"></hy-upload>

API ​

Upload Props ​

ParameterDescriptionTypeDefault
acceptAccepted file types; file is only supported on H5 (only the WeChat Mini Program supports configuring accept as all or media)stringimage
extensionFilter by file extension; each item cannot be an empty string. No filtering by default.string[][]
captureImage or video capture mode; when accept is image, optionally adding camera to capture can directly launch the camera('album' | 'camera')[]['album', 'camera']
compressedTakes effect when accept is video; whether to compress the videobooleantrue
cameraTakes effect when accept is video; optional values are back or front'back' | 'front'back
maxDurationTakes effect when accept is video; the maximum video recording duration, in secondsnumber60
uploadIconIcon of the upload area; only built-in icons are supportedstringIconConfig.UPLOAD
uploadIconColorColor of the icon in the upload areastring#D3D4D6
useBeforeReadWhether to enable the before-read eventbooleanfalse
previewFullImageWhether to show the component's built-in image preview featurebooleantrue
maxCountMaximum number of uploadsnumber52
disabledWhether to disable the componentbooleanfalse
imageModeCrop mode when previewing uploaded images, consistent with the image component's mode propertystringaspectFill
nameIdentifier, which can be retrieved in the second parameter of the callback functionstring''
sizeTypeoriginal for original images, compressed for compressed images; both by default; not effective on H5('original' | 'compressed')[]['original', 'compressed']
multipleWhether to enable multiple image selection; some Android devices do not support itbooleanfalse
deletableWhether to show the delete button for imagesbooleantrue
maxSizeMaximum size of a single selected file, in bytes (B); unlimited by defaultnumberNumber.MAX_VALUE
fileListList of already uploaded files to displayFileVo[][]
uploadTextHint text for the upload areastring''
widthWidth of the internal image preview area and the image selection button area; numbers default to the unit rpxstring | number80
heightHeight of the internal image preview area and the image selection button area; numbers default to the unit rpxstring | number80
beforeReadHandler function before reading(file, detail) => void-
afterReadHandler function after reading(file, detail) => void-
customStyleCustom external styles to applyCSSProperties-

fileList Data Structure ​

ParameterDescriptionTypeDefault
urlLocal address link of the uploaded filestring-
typeUploaded file type'image' | 'video' | 'file'-
thumbThumbnail URLstring-
sizeFile sizenumber-
isVideoWhether it is a videoboolean-
isImageWhether it is an imageboolean-
deletableWhether to show the delete buttonboolean-
statusUpload status'loading' | 'failed' | 'success'-
messageHint messagestring-
scheduleUpload progressstring | number-

Events ​

Event NameDescriptionCallback Parameters
afterReadHandler function after the file is read{ file: FileVo | FileVo[], name: string, index: number }
beforeReadHandler function before the file is read{ file: FileVo | FileVo[], name: string, index: number, callback: (ok) => void }
oversizeFile size exceeds the maximum allowed size{ file: FileVo | FileVo[], name: string, index: number }
clickPreviewTriggered when previewing an image in fullscreen{ file: FileVo, name: string, index: number }
deleteTriggered when an image is deleted{ file: FileVo, name: string, index: number }
errorTriggered on upload errorerror: any

Slots ​

Slot NameDescription
defaultCustom upload button content
triggerCustom area to trigger the upload

Typings ​

Type Definitions
ts
export interface FileVo {
    /** Local address link of the uploaded file */
    url?: string;
    /** Uploaded file type */
    type?: 'image' | 'video' | 'file';
    /** Thumbnail URL */
    thumb?: string;
    /** File size */
    size?: number;
    /** Whether it is a video */
    isVideo?: boolean;
    /** Whether it is an image */
    isImage?: boolean;
    /** Whether to show the delete button */
    deletable?: boolean;
    /** Upload status */
    status?: 'loading' | 'failed' | 'success';
    /** Hint message */
    message?: string;
    /** Upload progress */
    schedule?: string | number;
}

export type ReadFunctionVo = (file: FileVo, detail: { name: string; index: number }) => void;

export interface UploadFileParams {
    file: FileVo | FileVo[];
    name: string;
    index: number;
}

CSS Variables ​

Variable NameDescriptionDefault
--hy-upload-image-widthPreview image size80px
--hy-upload-text-font-sizeHint text font size11px
--hy-upload-radiusUpload item border radius2px
--hy-upload-item-marginUpload item outer margin0 8px 8px 0
--hy-upload-deletable-sizeDelete button size14px
--hy-upload-other-bgFile type background colorrgb(242, 242, 242)
--hy-upload-text-colorHint text colorFollows --hy-text-color--grey
12:33
battery