DropZone.vue
3.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
<script setup>
import {
useDropZone,
useFileDialog,
useObjectUrl,
} from '@vueuse/core'
const dropZoneRef = ref()
const fileData = ref([])
const { open, onChange } = useFileDialog({ accept: 'image/*' })
function onDrop(DroppedFiles) {
DroppedFiles?.forEach(file => {
if (file.type.slice(0, 6) !== 'image/') {
// eslint-disable-next-line no-alert
alert('Only image files are allowed')
return
}
fileData.value.push({
file,
url: useObjectUrl(file).value ?? '',
})
})
}
onChange(selectedFiles => {
if (!selectedFiles)
return
for (const file of selectedFiles) {
fileData.value.push({
file,
url: useObjectUrl(file).value ?? '',
})
}
})
useDropZone(dropZoneRef, onDrop)
</script>
<template>
<div class="flex">
<div class="w-full h-auto relative">
<div
ref="dropZoneRef"
class="cursor-pointer"
@click="() => open()"
>
<div
v-if="fileData.length === 0"
class="d-flex flex-column justify-center align-center gap-y-2 pa-12 drop-zone rounded"
>
<IconBtn
variant="tonal"
color="secondary"
class="rounded"
size="40"
>
<VIcon
size="24"
icon="ri-upload-2-line"
/>
</IconBtn>
<h4 class="text-h4">
Drag and drop your image here.
</h4>
<span class="text-disabled">or</span>
<VBtn
variant="outlined"
size="small"
>
Browse Images
</VBtn>
</div>
<div
v-else
class="d-flex justify-center align-center gap-3 pa-8 drop-zone flex-wrap"
>
<VRow class="match-height w-100">
<template
v-for="(item, index) in fileData"
:key="index"
>
<VCol
cols="12"
sm="4"
>
<VCard :ripple="false">
<VCardText
class="d-flex flex-column"
@click.stop
>
<VImg
:src="item.url"
width="200px"
height="150px"
class="w-100 mx-auto"
/>
<div class="mt-2">
<span class="clamp-text text-wrap">
{{ item.file.name }}
</span>
<span>
{{ item.file.size / 1000 }} KB
</span>
</div>
</VCardText>
<VCardActions>
<VBtn
variant="text"
block
@click.stop="fileData.splice(index, 1)"
>
Remove File
</VBtn>
</VCardActions>
</VCard>
</VCol>
</template>
</VRow>
</div>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.drop-zone {
border: 1px dashed rgba(var(--v-theme-on-surface), var(--v-border-opacity));
}
</style>