file-input.vue 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. <template>
  2. <div class="file-input"
  3. :class="{ active: drag }"
  4. @dragenter="dragenter"
  5. @dragleave="dragleave"
  6. @drop="drop">
  7. <input type="file"
  8. multiple
  9. @change="change">
  10. <img src="@/assets/icons/package-dependencies.svg">
  11. <div class="text">
  12. Click or drop a file here to upload it to the current project directory.
  13. </div>
  14. </div>
  15. </template>
  16. <script>
  17. export default {
  18. name: "file-input",
  19. props: ['url'],
  20. data: function() {
  21. return {
  22. drag: false
  23. }
  24. },
  25. methods: {
  26. change: function(event) {
  27. event.preventDefault();
  28. this.drag = false;
  29. const result = [];
  30. for (let i = 0; i < event.target.files.length; i++) {
  31. result.push(event.target.files[i]);
  32. }
  33. this.upload(result);
  34. },
  35. dragenter: function(event) {
  36. event.preventDefault();
  37. this.drag = true;
  38. },
  39. dragleave: function(event) {
  40. event.preventDefault();
  41. this.drag = false;
  42. },
  43. drop: function(event) {
  44. event.preventDefault();
  45. this.drag = false;
  46. if (event.dataTransfer.items) {
  47. const result = [];
  48. for (let i = 0; i < event.dataTransfer.items.length; i++) {
  49. if (event.dataTransfer.items[i].kind === 'file') {
  50. const file = event.dataTransfer.items[i].getAsFile();
  51. result.push(file);
  52. }
  53. }
  54. this.upload(result);
  55. }
  56. },
  57. upload: function(files) {
  58. for (let file of files) {
  59. const form = new FormData();
  60. form.append('file', file);
  61. form.append('size', file.size);
  62. fetch(this.url, {
  63. method: 'POST',
  64. body: form
  65. })
  66. .then(() => console.log('done'))
  67. .catch(e => console.log(e));
  68. }
  69. }
  70. }
  71. }
  72. </script>
  73. <style scoped>
  74. .file-input {
  75. position: relative;
  76. display: flex;
  77. flex-direction: column;
  78. justify-content: center;
  79. align-items: center;
  80. padding: 2rem;
  81. border: 1px dashed var(--primary);
  82. border-radius: 1rem;
  83. transition: background-color 2s, color 1s;
  84. }
  85. .file-input.active {
  86. background-color: var(--primary);
  87. color: white;
  88. }
  89. input {
  90. position: absolute;
  91. top: 0;
  92. left: 0;
  93. width: 100%;
  94. height: 100%;
  95. z-index: 9;
  96. opacity: 0;
  97. }
  98. img {
  99. width: 3rem;
  100. margin-bottom: 1rem;
  101. opacity: 0.6;
  102. transition: opacity 1s, filter 1s;
  103. }
  104. .file-input.active img {
  105. opacity: 1;
  106. filter: invert(1);
  107. }
  108. </style>