| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071 |
- <template>
- <div
- class="file-input"
- :class="{ 'drag-over': isDragOver }"
- @click="handleClick()"
- @dragenter.prevent="handleDragEnter"
- @dragover.prevent="handleDragOver"
- @dragleave.prevent="handleDragLeave"
- @drop.prevent="handleDrop"
- >
- <slot></slot>
- <input
- class="input"
- type="file"
- name="upload"
- ref="inputRef"
- :accept="accept"
- @change="$event => handleChange($event)"
- @click.stop
- >
- </div>
- </template>
- <script lang="ts" setup>
- import { ref, useTemplateRef } from 'vue'
- withDefaults(defineProps<{
- accept?: string
- }>(), {
- accept: 'image/*',
- })
- const emit = defineEmits<{
- (event: 'change', payload: FileList): void
- }>()
- const inputRef = useTemplateRef<HTMLInputElement>('inputRef')
- const isDragOver = ref(false)
- const handleClick = () => {
- if (!inputRef.value) return
- inputRef.value.value = ''
- inputRef.value.click()
- }
- const handleChange = (e: Event) => {
- const files = (e.target as HTMLInputElement).files
- if (files) emit('change', files)
- }
- const handleDragEnter = () => {
- isDragOver.value = true
- }
- const handleDragOver = () => {
- isDragOver.value = true
- }
- const handleDragLeave = () => {
- isDragOver.value = false
- }
- const handleDrop = (e: DragEvent) => {
- isDragOver.value = false
- const files = e.dataTransfer?.files
- if (files && files.length > 0) {
- emit('change', files)
- }
- }
- </script>
- <style lang="scss" scoped>
- .input {
- display: none;
- }
- </style>
|