Preview Updated 2026-05-10

Dropzone

File picker that accepts both drag and click, with built-in file list, progress bar, and reject callback.

Basic usage

v-model binds a File[]. Drag files into the dashed border, or click the area to open the file dialog. Selected files appear in a compact list with size and a remove button per row.

点击或拖拽文件到此区域上传
支持拖入或点击选择,多文件均可
<script setup lang="ts">
import { ref } from 'vue';
import { CfDropzone } from '@chufix-design/vue';

const files = ref<File[]>([]);
</script>

<template>
<CfDropzone v-model="files" hint="Drop files here or click to select; multi-file supported" />
</template>
import { useState } from 'react';
import { CfDropzone } from '@chufix-design/react';

export default function Demo() {
const [files, setFiles] = useState<File[]>([]);
return (
  <CfDropzone
    value={files}
    hint="Drop files here or click to select; multi-file supported"
    onChange={setFiles}
  />
);
}

Constraints and reject callback

accept / maxSize / maxFiles define what’s accepted. Any rejected file is reported through the reject (Vue) / onReject (React) callback with a specific reason ('too-large' | 'too-many' | 'wrong-type' | 'duplicate').

点击或拖拽文件到此区域上传
只接受图片,单文件最大 1 MB,最多 3 个
<script setup lang="ts">
import { ref } from 'vue';
import { CfDropzone, type DropzoneRejection } from '@chufix-design/vue';

const files = ref<File[]>([]);

function onReject(items: DropzoneRejection[]) {
// handle as needed, e.g. show a Toast
}
</script>

<template>
<CfDropzone
  v-model="files"
  accept="image/*"
  :max-size="1024 * 1024"
  :max-files="3"
  hint="Images only, up to 1 MB each, max 3 files"
  @reject="onReject"
/>
</template>
import { useState } from 'react';
import { CfDropzone, type DropzoneRejection } from '@chufix-design/react';

export default function Demo() {
const [files, setFiles] = useState<File[]>([]);
return (
  <CfDropzone
    value={files}
    accept="image/*"
    maxSize={1024 * 1024}
    maxFiles={3}
    hint="Images only, up to 1 MB each, max 3 files"
    onChange={setFiles}
    onReject={(items: DropzoneRejection[]) => console.warn(items)}
  />
);
}

Upload progress

Pass external upload state via statuses (Vue / React); its length must match modelValue / value. status is 'pending' | 'uploading' | 'success' | 'error'; progress is 0–100; error is shown only when status === 'error'.

The demo below fakes uploads with setTimeout. In a real project, wire statuses to the progress events of fetch / XHR.

点击或拖拽文件到此区域上传
选择文件后会模拟上传进度
<script setup lang="ts">
import { ref, watch } from 'vue';
import { CfDropzone, type DropzoneFileStatus } from '@chufix-design/vue';

const files = ref<File[]>([]);
const statuses = ref<DropzoneFileStatus[]>([]);

watch(files, (next) => {
statuses.value = next.map((_, i) =>
  statuses.value[i] ?? { progress: 0, status: 'pending' }
);
});
</script>

<template>
<CfDropzone v-model="files" :statuses="statuses" />
</template>
import { useState, useEffect } from 'react';
import { CfDropzone, type DropzoneFileStatus } from '@chufix-design/react';

export default function Demo() {
const [files, setFiles] = useState<File[]>([]);
const [statuses, setStatuses] = useState<DropzoneFileStatus[]>([]);
useEffect(() => {
  setStatuses((prev) =>
    files.map((_, i) => prev[i] ?? { progress: 0, status: 'pending' })
  );
}, [files]);
return <CfDropzone value={files} statuses={statuses} onChange={setFiles} />;
}

API

PropTypeDefaultDescription
modelValue (Vue) / value (React)File[][]Current files
acceptstringSame as <input>’s accept, comma-separated; supports image/* and .ext
multiplebooleantrueSingle / multi-select; false makes a new selection replace the previous value
maxSizenumberMax bytes per file
maxFilesnumberMax total count
disabledbooleanfalseDisabled
size'sm' | 'md' | 'lg''md'Size
hintstringSubtitle text
statusesDropzoneFileStatus[]Per-file status array: { progress, status, error }
hideListbooleanfalseSkip the built-in file list and render your own

Events: update:modelValue / change / reject / remove (React: onChange / onReject / onRemove).

Slots: the default slot replaces the title area; #icon replaces the default upload illustration (default comes from CfStatusIllustration variant="upload").

反馈与讨论

Dropzone · Discussion

0
0 / 600
一键发送
正在加载评论...