1 <template> 2 <label class="file-select ma-5"> 3 <div 4 class="select-button" 5 @dragover="dragover" 6 @dragleave="dragleave" 7 @drop="drop" 8 > 9 <span v-if="label">{{ !fileName ? label : '' }}</span> 10 <span v-else>Select File</span> 11 <div v-if="fileName"> File selected: {{ fileName }}</div> 12 </div> 13 <input 14 ref="file" 15 type="file" 16 accept=".zip" 17 @change="handleFileChange" 18 > 19 </label> 20 </template> 21 22 <script> 23 export default { 24 props: { 25 label: { 26 type: String, 27 default: '', 28 }, 29 }, 30 data() { 31 return { 32 fileName: '', 33 } 34 }, 35 methods: { 36 handleFileChange(event) { 37 this.$emit('file-select', this.$refs.file.files) 38 this.fileName = this.$refs.file.files[0].name 39 }, 40 dragover(event) { 41 event.preventDefault() 42 if (!event.currentTarget.classList.contains('file-hover')) { 43 event.currentTarget.classList.add('file-hover') 44 } 45 }, 46 dragleave(event) { 47 event.currentTarget.classList.remove('file-hover') 48 }, 49 drop(event) { 50 event.preventDefault() 51 this.$refs.file.files = event.dataTransfer.files 52 this.handleFileChange(event) 53 event.currentTarget.classList.remove('file-hover') 54 }, 55 }, 56 } 57 </script> 58 59 <style scoped> 60 .file-select > .select-button { 61 padding: 3rem; 62 border-radius: 0.3rem; 63 border: 4px dashed #eaebec; 64 text-align: center; 65 font-weight: bold; 66 cursor: pointer; 67 } 68 69 .file-select > input[type='file'] { 70 display: none; 71 } 72 73 .file-hover { 74 background-color: #95e995; 75 } 76 </style>