Skip to content
On this page

Upload 上传

文件选择上传和拖拽上传控件。

基础用法

用户点击按钮弹出文件选择框。插槽trigger用于传入触发文件选择的内容,插槽tip用户传入提示信息。

prompt message.
<>
<template>
    <div class="kl-upload">
        <kl-upload
            v-model:files="files"
            action="http://localhost:3000/file/upload-multiple"
            name="files"
            multiple
            @success="handleSuccess"
            @error="handleError"
        >
            <template #trigger>
                <kl-button>Click to upload</kl-button>
            </template>
            <template #tip>
                <div class="upload-tip">prompt message.</div>
            </template>
        </kl-upload>
    </div>
</template>

<script lang="ts" setup>
import { ref } from 'vue'
import { KlMessage } from '@kunlun-design/components'
interface FileItem {
    id: string
    name: string
    percent: number
    rawFile: File
    size: number
    status: 'ready' | 'uploading' | 'success' | 'failure'
    type: string
}

const files = ref<FileItem[]>([])

const handleSuccess = () => {
    KlMessage.success('上传成功')
}

const handleError = () => {
    KlMessage.error('上传失败')
}
</script>

<style lang="scss" scoped>
.upload-tip {
    font-size: 12px;
    margin-top: 6px;
}
</style>

限制上传文件数量

通过limit属性限制上传文件数量,当超过限制时,会触发 onExceed 事件。

<>
<template>
    <div class="kl-upload">
        <kl-upload
            v-model:files="files"
            action="http://localhost:3000/file/upload-multiple"
            name="files"
            multiple
            :limit="3"
            @success="handleSuccess"
            @error="handleError"
            @exceed="handleExceed"
        >
            <template #trigger>
                <kl-button>Click to upload</kl-button>
            </template>
        </kl-upload>
    </div>
</template>

<script lang="ts" setup>
import { ref } from 'vue'
import { KlMessage } from '@kunlun-design/components'
interface FileItem {
    id: string
    name: string
    percent: number
    rawFile: File
    size: number
    status: 'ready' | 'uploading' | 'success' | 'failure'
    type: string
}

const files = ref<FileItem[]>([])

const handleSuccess = () => {
    KlMessage.success('上传成功')
}

const handleError = () => {
    KlMessage.error('上传失败')
}

const handleExceed = () => {
    KlMessage.warning('文件数量超过限制')
}
</script>

<style lang="scss" scoped>
.upload-tip {
    font-size: 12px;
    margin-top: 6px;
}
</style>

用户头像

on-before-upload 钩子中限制用户上传文件的格式和大小。

jpg files with a size less than 2MB.
<>
<template>
    <div class="kl-upload">
        <kl-upload
            v-model:files="files"
            action="http://localhost:3000/file/upload-single"
            name="file"
            :show-file-list="false"
            @success="handleSuccess"
            @error="handleError"
            @before-upload="handleBeforeUpload"
        >
            <template #trigger>
                <div class="avatar">
                    <img v-if="imageUrl" :src="imageUrl" alt="" />
                    <KlSystemAdd v-else size="50" />
                </div>
            </template>
            <template #tip>
                <div class="upload-tip">jpg files with a size less than 2MB.</div>
            </template>
        </kl-upload>
    </div>
</template>

<script lang="ts" setup>
import { ref } from 'vue'
import { KlMessage } from '@kunlun-design/components'
interface FileItem {
    id: string
    name: string
    percent: number
    rawFile: File
    size: number
    status: 'ready' | 'uploading' | 'success' | 'failure'
    type: string
}

const files = ref<FileItem[]>([])
const imageUrl = ref<string>('')

const handleSuccess = (respance: any, uploadFile: FileItem) => {
    KlMessage.success('上传成功')
    imageUrl.value = URL.createObjectURL(uploadFile.rawFile)
}

const handleError = () => {
    KlMessage.error('上传失败')
}

const handleBeforeUpload = (uploadFile: FileItem) => {
    console.log(URL.createObjectURL(uploadFile.rawFile))
    if (uploadFile.type !== 'image/jpeg') {
        KlMessage.error('Avatar picture must be JPG format!')
        return false
    } else if (uploadFile.size / 1024 / 1024 > 2) {
        KlMessage.error('Avatar picture size can not exceed 2MB!')
        return false
    }
    return true
}
</script>

<style lang="scss" scoped>
.upload-tip {
    font-size: 12px;
    margin-top: 6px;
}

.avatar {
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 200px;
    height: 200px;
    border: 2px dashed #ccc;
    border-radius: 10px;
    transition: all 0.3s;
    color: #ccc;
    cursor: pointer;

    img {
        width: 100%;
    }

    &:hover {
        border-color: #2b8e41;
        color: #2b8e41;
    }
}
</style>

拖拽上传

设置 drag属性为 true,你可以将文件拖拽到特定区域以进行上传。

nametrigger的插槽会传递一个dragging属性,boolean 类型,用于判断拖拽元素是否处于拖拽区域中,你可以基于此特性自定义拽入样式。

Drop file here or click to upload

<>
<template>
    <div class="kl-upload">
        <kl-upload
            v-model:files="files"
            action="http://localhost:3000/file/upload-multiple"
            name="files"
            multiple
            drag
            @success="handleSuccess"
            @error="handleError"
        >
            <template #trigger="{ dragging }">
                <div :class="['drag-area', { dragging: dragging }]">
                    <div class="drag-msg">
                        <KlOtherUploadFill size="50" />
                        <p>Drop file here or click to upload</p>
                    </div>
                </div>
            </template>
        </kl-upload>
    </div>
</template>

<script lang="ts" setup>
import { ref } from 'vue'
import { KlMessage } from '@kunlun-design/components'
interface FileItem {
    id: string
    name: string
    percent: number
    rawFile: File
    size: number
    status: 'ready' | 'uploading' | 'success' | 'failure'
    type: string
}

const files = ref<FileItem[]>([])

const handleSuccess = () => {
    KlMessage.success('上传成功')
}

const handleError = () => {
    KlMessage.error('上传失败')
}
</script>

<style lang="scss" scoped>
.dragging {
    border-color: #2b8e41 !important;
    background-color: #f0f9eb;
}

.drag-area {
    display: flex;
    justify-content: center;
    box-sizing: border-box;
    padding: 100px 100px;
    height: 300px;
    border-radius: 10px;
    border: 2px dashed#ccc;
    transition: all 0.3s;

    .drag-msg {
        display: flex;
        flex-direction: column;
        justify-content: space-between;
        align-items: center;
        color: #85878b;

        p {
            padding: 0;
            margin: 0;
        }
    }

    &:hover {
        border-color: #2b8e41;
    }
}
</style>

上传 API

属性

名称描述类型默认值必填
files文件列表FileItem[][]
name上传的文件字段名,需要和后端约定stringfile
action请求 URLstring
method请求方法stringpost
headers设置上传的请求头部Record<string, string>
limit允许上传文件的最大数量number
multiple是否支持多选文件booleanfalse
show-file-list是否显示已上传文件列表booleantrue
data上传时附带的额外参数Record<string, any>
drag是否启用拖拽上传booleanflase
on-exceed当超出限制时,执行的钩子函数(files: FileItem[], uploadFiles: FileItem[]) => void
on-change文件状态改变时的钩子,上传成功和上传失败时都会被调用(uploadFile: FileItem, uploadFiles: FileItem[]) => void
on-before-upload上传文件之前的钩子,参数为上传的文件, 若返回 false,则取消上传(uploadFile: FileItem) => void
on-preview点击文件列表中已上传的文件时的钩子(file: FileItem) => void
on-before-remove文件列表移除文件之前的钩子,若返回 false,则取消移除操作(file: FileItem, files: FileItem[]) => boolean
on-remove文件列表移除文件时的钩子(file: FileItem, files: FileItem[]) => void
on-success文件上传成功时的钩子(response: any, uploadFile: FileItem, uploadFiles: FileItem[]) => void
on-error文件上传失败时的钩子(error: Error, uploadFile: FileItem, uploadFiles: FileItem[]) => void
on-progress文件上传时的钩子(percent: number, uploadFile: FileItem, uploadFiles: FileItem[]) => void

插槽

名称描述
trigger触发文件选择框的内容
tip提示说明文字

Released under the MIT License.