{
"slug": "dragupload",
"end": "vue3",
"curated": true,
"summary": "Vue 3 拖拽上传:拖入或点击选择文件,内部模拟上传进度并生成图片缩略图。",
"usage": [
"本端没有任何 props、emit 与插槽, 挂上即用,文件列表由内部 files ref 维护(DragUpload.vue3.vue:25)。",
"拖拽事件用 @dragover.prevent / @drop.prevent 组合,避免浏览器直接打开被拖入的文件(DragUpload.vue3.vue:3)。",
"点击区域通过 file.click() 转发到隐藏的 input[type=file],选完即把 e.target.value 清空,便于重复选同一个文件(DragUpload.vue3.vue:42)。",
"图片且小于 2MB 时用 FileReader.readAsDataURL 生成缩略图,其它类型统一显示「文件」文字(DragUpload.vue3.vue:33)。",
"进度是 setInterval 每 220ms 随机递增的演示数据,到 100 即标记 done 并清除定时器(DragUpload.vue3.vue:44)。"
],
"bestPractices": [
"进度与完成态都是本地模拟,没有真实上传通道,接入后端时需要自行替换 simulate 并接管 files 结构(DragUpload.vue3.vue:44)。",
"删除是按下标 id 过滤数组,id 由时间戳加随机串生成;同批次内不会重复,但长时间挂载后 id 会越来越长(DragUpload.vue3.vue:31)。",
"thumb 只在图片且小于 2MB 时生成,其余类型 key 仍存在但为空串,模板用 v-if 分支渲染占位文字(DragUpload.vue3.vue:10)。"
],
"apiCarrier": {
"kind": "props",
"note": "本端无 defineProps / defineEmits / defineExpose,唯一可用的定制面是模板类名与 is-over 状态类,因此表中列出的是样式钩子而非 prop。",
"table": [
{
"name": "kole-upload-drop",
"type": "class",
"desc": "拖拽投放区容器类名;拖拽经过时附加 is-over 状态类"
},
{
"name": "kole-upload-item",
"type": "class",
"desc": "单个文件行容器,进度条与状态文字均在此基础上挂子类"
},
{
"name": "kole-upload-del",
"type": "class",
"desc": "删除按钮类名,点击后从 files 中移除该行"
},
{
"name": "is-over",
"type": "state class",
"desc": "拖拽悬停态::class=\"{ 'is-over': over }\",可用于高亮投放区"
}
]
},
"a11y": [
"拖拽区是 div + @click,没有 role、tabindex 与键盘处理,纯键盘用户完全无法选择文件;建议由业务在其上叠加真实 button(DragUpload.vue3.vue:3)。",
"隐藏的 file input 用 style=\"display:none\" 且无 label,读屏与键盘都访问不到;进度条只有数字百分比,没有 role=\"progressbar\"(DragUpload.vue3.vue:7)。"
],
"resources": [
{
"file": "frameworks/DragUpload.vue3.vue",
"kind": "Vue 3 组件",
"desc": "dragupload 的 Vue 3(