Skip to content

Upload 上传组件

该组件用于上传文件场景,支持图片、视频等多种文件类型的上传

📌平台差异说明

APP(vue)H5微信小程序支付宝小程序

🏯基本使用示例

html
<!-- 全局使用 -->
<hy-upload :fileList="list"></hy-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: '上传中',
        url: file.url,
        schedule: 0
    });
    // 模拟上传进度
    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 = '上传成功';
        }
    }, 200);
}

限制上传数量

通过maxCount设置最大上传数量,默认52张。

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

多张图片上传

设置multiple开启多选模式,部分安卓机型不支持。

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: '上传中',
                url: item.url,
                schedule: 0
            });
            // 模拟单个文件上传
            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 = '上传成功';
                }
            }, 200);
        });
    }
}

限制文件大小

通过maxSize设置单个文件的最大大小,单位为字节(byte)。

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) => {
    // 处理上传逻辑
};

const onOversize = () => {
    uni.showToast({
        title: '图片超出500KB限制',
        icon: 'none'
    });
}
</script>

上传视频

设置accept="video"限制只上传视频文件。

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: '上传成功',
        url: file.url
    });
}
</script>

自定义上传按钮

使用默认插槽自定义上传按钮样式。

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">点击上传</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>

自定义触发区域

使用trigger插槽自定义触发上传的区域。

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">拖拽或点击上传</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禁用上传功能。

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">上传已禁用</text>
        </view>
    </hy-upload>
</template>

隐藏删除按钮

设置deletable="false"隐藏删除按钮。

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

自定义尺寸

通过widthheight自定义上传区域的尺寸。

html
<hy-upload 
    :fileList="list" 
    :width="120" 
    :height="120" 
    upload-text="大尺寸"
    @afterRead="afterRead"
></hy-upload>

上传失败状态

设置status="failed"显示上传失败状态。

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: '上传失败',
        url: ''
    }
]);
</script>

图片裁剪模式

通过imageMode设置预览图片的裁剪模式,与image组件的mode属性一致。

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

控制预览

通过previewFullImage控制是否显示全屏预览功能。

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

选择模式

通过capture设置图片或视频的拾取模式。

html
<!-- 仅从相册选择 -->
<hy-upload :fileList="list" :capture="['album']"></hy-upload>

<!-- 仅从相机拍摄 -->
<hy-upload :fileList="list" :capture="['camera']"></hy-upload>

<!-- 相册和相机都支持 -->
<hy-upload :fileList="list" :capture="['album', 'camera']"></hy-upload>

原图/压缩图

通过sizeType控制所选图片的尺寸类型。

html
<!-- 只选择原图 -->
<hy-upload :fileList="list" :sizeType="['original']"></hy-upload>

<!-- 只选择压缩图 -->
<hy-upload :fileList="list" :sizeType="['compressed']"></hy-upload>

<!-- 原图和压缩图都支持 -->
<hy-upload :fileList="list" :sizeType="['original', 'compressed']"></hy-upload>

API

Upload Props

参数说明类型默认值
accept接受的文件类型,file只支持H5(只有微信小程序才支持把accept配置为all、media)stringimage
extension根据文件拓展名过滤,每一项都不能是空字符串。默认不过滤。string[][]
capture图片或视频拾取模式,当accept为image类型时设置capture可选额外camera可以直接调起摄像头('album' | 'camera')[]['album', 'camera']
compressed当accept为video时生效,是否压缩视频booleantrue
camera当accept为video时生效,可选值为back或front'back' | 'front'back
maxDuration当accept为video时生效,拍摄视频最长拍摄时间,单位秒number60
uploadIcon上传区域的图标,只能内置图标stringIconConfig.UPLOAD
uploadIconColor上传区域的图标的颜色string#D3D4D6
useBeforeRead是否开启文件读取前事件booleanfalse
previewFullImage是否显示组件自带的图片预览功能booleantrue
maxCount最大上传数量number52
disabled是否禁用组件booleanfalse
imageMode预览上传的图片时的裁剪模式,和image组件mode属性一致stringaspectFill
name标识符,可以在回调函数的第二项参数中获取string''
sizeTypeoriginal 原图,compressed 压缩图,默认二者都有,H5无效('original' | 'compressed')[]['original', 'compressed']
multiple是否开启图片多选,部分安卓机型不支持booleanfalse
deletable是否显示删除图片的按钮booleantrue
maxSize选择单个文件的最大大小,单位B(byte),默认不限制numberNumber.MAX_VALUE
fileList显示已上传的文件列表FileVo[][]
uploadText上传区域的提示文字string''
width内部预览图片区域和选择图片按钮的区域宽度,单位rpxstring | number80
height内部预览图片区域和选择图片按钮的区域高度,单位rpxstring | number80
beforeRead读取前的处理函数(file, detail) => void-
afterRead读取后的处理函数(file, detail) => void-
customStyle自定义需要用到的外部样式CSSProperties-

fileList 数据结构

参数说明类型默认值
url上传文件本地地址链接string-
type上传文件类型'image' | 'video' | 'file'-
thumb缩略图地址string-
size文件大小number-
isVideo是否视频boolean-
isImage是否图片boolean-
deletable是否显示删除按钮boolean-
status上传状态'loading' | 'failed' | 'success'-
message提示信息string-
schedule上传进度string | number-

Events

事件名说明回调参数
afterRead文件读取后的处理函数{ file: FileVo | FileVo[], name: string, index: number }
beforeRead文件读取前的处理函数{ file: FileVo | FileVo[], name: string, index: number, callback: (ok) => void }
oversize文件大小超出最大允许大小{ file: FileVo | FileVo[], name: string, index: number }
clickPreview全屏预览图片时触发{ file: FileVo, name: string, index: number }
delete删除图片时触发{ file: FileVo, name: string, index: number }
error上传错误时触发error: any

Slots

插槽名说明
default自定义上传按钮内容
trigger自定义触发上传的区域

Typings

类型说明
ts
export interface FileVo {
    /** 上传文件本地地址链接 */
    url?: string
    /** 上传文件类型 */
    type?: 'image' | 'video' | 'file'
    /** 缩略图地址 */
    thumb?: string
    /** 文件大小 */
    size?: number
    /** 是否视频 */
    isVideo?: boolean
    /** 是否图片 */
    isImage?: boolean
    /** 是否显示删除按钮 */
    deletable?: boolean
    /** 上传状态 */
    status?: 'loading' | 'failed' | 'success'
    /** 提示信息 */
    message?: string
    /** 上传进度 */
    schedule?: string | number
}

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

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