VueUse 10.9.0 useDropZone设置dataTypes:['image/*']失效求助
问题原因
VueUse v10.9.0 的 useDropZone 对 dataTypes 参数采用严格字符串匹配逻辑,并不支持 image/* 这类通配符规则。当你设置 dataTypes: ['image/*'] 时,只有文件的 type 属性恰好等于 image/* 才会被识别,而实际图片文件的 type 都是具体格式(比如 image/png、image/jpeg),自然匹配失败,导致拖拽功能失效。而指定 image/png 时,因为和对应文件的 type 严格相等,所以能正常工作。
解决方案
不需要依赖 dataTypes 参数,在 onDrop 回调中手动过滤图片文件即可,同时可以兼容部分文件 type 为空的情况(比如某些系统中拖拽的图片可能没有正确的 MIME 类型):
<script setup lang="ts"> import { ref } from 'vue' import { useDropZone} from '@vueuse/core' const imageFilesData = ref<{ name: string, size: number, type: string, lastModified: number }[]>([]) function onImageDrop(files: File[] | null) { imageFilesData.value = [] if (files) { // 过滤图片文件:优先检查 MIME type,其次检查文件名后缀 const imageFiles = files.filter(file => { if (file.type.startsWith('image/')) return true // 处理 type 为空的情况,通过后缀判断 const ext = file.name.split('.').pop()?.toLowerCase() return ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'].includes(ext || '') }) // 只保留单张图片 if (imageFiles.length > 0) { imageFilesData.value = [imageFiles[0]].map(file => ({ name: file.name, size: file.size, type: file.type, lastModified: file.lastModified, })) } } } const imageDropZoneRef = ref<HTMLElement>() // 移除 dataTypes 参数,由回调自行处理过滤 const { isOverDropZone: isOverImageDropZone } = useDropZone(imageDropZoneRef, { onDrop: onImageDrop }) </script> <template> <div class="flex flex-col gap-2"> <div class="w-full h-auto relative"> <p>Drop files on to drop zones</p> <div grid="~ cols-2 gap-2"> <div ref="imageDropZoneRef" class="flex flex-col w-full min-h-[200px] h-auto bg-gray justify-center items-center mt-6 rounded" > <div class="font-bold mb-2"> Image DropZone </div> <div> isOverDropZone: <span :class="isOverImageDropZone ? 'text-green-600 shadow-1' : 'text-red-600 shadow-1'">{{ isOverImageDropZone }}</span> </div> <div class="flex flex-wrap justify-center items-center"> <div v-for="(file, index) in imageFilesData" :key="index" class="w-[200px] bg-gray-200 m-2 p-6"> <p>Name: {{ file.name }}</p> <p>Size: {{ file.size }}</p> <p>Type: {{ file.type }}</p> <p>Last modified: {{ file.lastModified }}</p> </div> </div> </div> </div> </div> </div> </template>
补充说明
如果需要保留拖拽时的视觉反馈(比如只有拖拽图片时才触发 isOverDropZone),可以手动监听拖拽事件,自定义判断逻辑:
// 在 setup 中添加 import { useEventListener } from '@vueuse/core' const isOverImageDropZone = ref(false) useEventListener(imageDropZoneRef, 'dragover', (e) => { e.preventDefault() const items = Array.from(e.dataTransfer?.items || []) const hasImage = items.some(item => { if (item.kind === 'file') { const file = item.getAsFile() if (file) { return file.type.startsWith('image/') || ['jpg','jpeg','png','gif','bmp','webp'].includes(file.name.split('.').pop()?.toLowerCase() || '') } } return false }) isOverImageDropZone.value = hasImage }) useEventListener(imageDropZoneRef, 'dragleave', () => { isOverImageDropZone.value = false })
内容的提问来源于stack exchange,提问作者Anatoly Lindemann
相关产品推荐
相关产品推荐

