ドラッグ&ドロップでファイルアプロードをVue.JSで実装する

最近はファイルのアップロード画面にドラッグ&ドロップが当たり前のように実装されるようになりました。画面がブラウザから離れるのであまり好きなUIではないのですが、案件としてリクエストがあったので実装です。

ボタンを押した際に通常のファイル選択UIが表示されるようにし、かつドラッグ&ドロップ対応です。
プレビューや送信処理は記述せず、アップされたファイルのサイズとファイル情報だけ表示するものです。

目次

HTML

index.html

<!DOCTYPE html>
<html lang="en">

<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>ファイルアップロード</title>
	<link rel="stylesheet" href="styles.css">
</head>

<body>
	<div id="app">
		<div class="file-upload">

			<input type="file" ref="fileInput" @change="handleFileChange" class="file-input" style="display: none;">

			<div class="drop-area" @dragover.prevent @drop="handleDrop">
				<button @click="$refs.fileInput.click()" class="file-select-button">ファイルを選択</button>
				ドラッグ&ドロップするか、ファイルを選択してください
			</div>
		</div>
		<div class="file-preview" v-if="file">
			<p><strong>選択したファイル:</strong> {{ file.name }}</p>
			<p><strong>ファイルタイプ:</strong> {{ file.type }}</p>
			<p><strong>ファイルサイズ:</strong> {{ formatSize(file.size) }}</p>
		</div>
	</div>
	<script src="https://unpkg.com/vue@3.0.0/dist/vue.global.prod.js"></script>
	<script src="app.js"></script>
</body>

</html>

JavaScript(Vue)

app.js

const app = Vue.createApp({
  data() {
    return {
      file: null,
    };
  },
  methods: {
    handleFileChange(event) {
      const selectedFile = event.target.files[0];
      this.file = selectedFile;
    },
    handleDrop(event) {
      event.preventDefault();
      const droppedFile = event.dataTransfer.files[0];
      this.file = droppedFile;
    },
    formatSize(bytes) {
      const sizes = ["Bytes", "KB", "MB", "GB", "TB"];
      if (bytes === 0) return "0 Byte";
      const i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
      return Math.round(bytes / Math.pow(1024, i), 2) + " " + sizes[i];
    },
  },
});

app.mount("#app");

CSS

styles.css

body {
  font-family: Arial, sans-serif;
  text-align: center;
  background-color: #f0f0f0;
}

.file-upload {
  margin: 20px;
}

.file-input {
  display: none;
}

.drop-area {
  border: 2px dashed #ccc;
  padding: 20px;
  cursor: pointer;
  background-color: #fff;
}

.file-preview {
  background-color: #fff;
  margin: 20px;
  padding: 10px;
  border: 1px solid #ccc;
}
よかったらシェアしてね!
  • URLをコピーしました!

この記事を書いた人

株式会社ねこすけの代表をしています。
2005年に創業しWebマーケティングを実践するためのコンサルティング、サイト構築、サイト運用、システム開発を行っています。
会員・顧客属性を利用したコンテンツ管理を得意としており、協会サイト、多ブランドのECサイト、会員向けコンテンツサイトなどを構築運営しています。Webマーケティングを進めてるのにパートナーがほしいと感じている方、ご相談ください。
月に1度のミーティングから細かなサイト保守まで必要な部分での対応が可能です。 問い合わせ

目次