JSFiddle - React, Tailwind, and code Playground
by ChangJoo Park
HTML
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<div id="app">
<file-drop placeholder="파일을 드래그앤드롭으로 가져오세요."></file-drop>
</div>
<template id="file-drop">
<div>
<div
id="drop-zone"
v-bind:class="[isDragging?'drag-over':'']"
v-on:dragover="isDragging=true"
v-on:dragenter="isDragging=true"
v-on:dragleave="isDragging=false"
>
<div class="text-wrap">
<span>{{placeholder}}</span>
</div>
<input type="file" @change="onChange" multiple>
</div>
<div>
<button v-on:click="imageList=[];">초기화</button>
</div>
<div v-if="imageList.length > 0">
<div v-for="item in imageList">
<img v-bind:src="item">
</div>
</div>
</div>
</template>
CSS
.drag-over {
background-color:#2881DD !important;
boder:2px dashed #2881DD !important;
color:white;
}
#drop-zone {
width:300px;
height:200px;
background-color:white;
border:2px dashed black;
border-radius:10px;
position: relative;
}
.text-wrap {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
}
#drop-zone input {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
opacity: 0;
}
img {
height: 100px;
}
button {
width: 300px;
height:30px;
}
JavaScript
Vue.component('file-drop', {
template: '#file-drop',
props: ['placeholder'],
data: function() {
return {
imageList : [],
isDragging : false
};
},
methods: {
onChange: function(e) {
this.isDragging = false;
var files = e.target.files || e.dataTransfer.files;
if(files.length == 0) {
return;
}
this.addImages(files);
e.target.value = '';
},
addImages: function(files) {
var self = this;
for(var i=0; i < files.length; i++) {
var file = files[i];
var reader = new FileReader();
if(file.type.match(/image.*/)) {
reader.onload = function(e) {
self.imageList.push(e.target.result);
}
reader.readAsDataURL(file);
}
}
},
reset: function(e) {
}
}
});
new Vue({
el: '#app'
});