<main>
  <div id="app" @dragover.prevent @drop.prevent>
    <div class="container" @dragleave="fileDragOut" @dragover="fileDragIn" @drop="handleFileDrop" @drop="fileDragOut" v-bind:style="{ 'background-color': color }">
      Add your files here:
      <br>
      <div class="file-wrapper">
        <input type="file" name="file-input" multiple="True" @change="handleFileInput" > Click or drag to insert.
      </div>
      <ul>
        <li v-for="(file, index) in files">
          {{ file.name }} ({{ file.size }} b)
          <button @click="removeFile(index)" title="Remove">X</button>
        </li>
      </ul>
    </div>
  </div>
</main>
body,html{
  height: 100%;
}
main {
  margin-top: 30px;
  height: 100%;
}
.container {
  border: 2px dashed pink;
  min-height: 150px;
}
#app {
  border: 1px solid yellow;
  height: 100vh;
}
.file-wrapper {
  text-align: center;
  width: 300px;
  height: 5em;
  vertical-align: middle;
  display: table-cell;
  position: relative;
  overflow: hidden;
  background: gray; /* and other things to make it pretty */
}


.file-wrapper input {
    position: absolute;
    top: 0;
    right: 0; /* not left, because only the right part of the input seems to
                 be clickable in some browser I can't remember */
    cursor: pointer;
    opacity: 0.0;
    filter: alpha(opacity=0); /* and all the other old opacity stuff you
                                 want to support */
    font-size: 300px; /* wtf, but apparently the most reliable way to make
                         a large part of the input clickable in most browsers */
    height: 200px;
}
var app = new Vue({
  el: '#app',
  data: {
    files: [],
    color: '#444444',
  },
  methods: {
    handleFileDrop(e) {
      let droppedFiles = e.dataTransfer.files;
      if(!droppedFiles) return;
      // this tip, convert FileList to array, credit: https://www.smashingmagazine.com/2018/01/drag-drop-file-uploader-vanilla-js/
      ([...droppedFiles]).forEach(f => {
    
    this.files.push(f);
      });
      this.color="#444444"
    },
    handleFileInput(e) {
      let files = e.target.files;
      files = e.target.files
            if(!files) return;
      // this tip, convert FileList to array, credit: https://www.smashingmagazine.com/2018/01/drag-drop-file-uploader-vanilla-js/
      ([...files]).forEach(f => {
    
    this.files.push(f);
      });
    },
    removeFile(fileKey){
      this.files.splice(fileKey, 1)
    },
    fileDragIn(){
      // alert("oof")
      // alert("color")
      this.color="white"
    },
    fileDragOut(){
      this.color="#444444"
    }
  }
})

External CSS

  1. https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css