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'
});