【Vue.js】ドラッグ&ドロップで、ファイルアップロードできるコンポーネントを作る。
2018-12-11見た目はこのような感じのを想定しています!
テンプレート部分の説明
こんな感じで作ります!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
<template> <div :class="[{'-drag': isDrag == 'new'}]" //★① @dragover.prevent="checkDrag($event, 'new', true)"//★② @dragleave.prevent="checkDrag($event, 'new', false)"//★③ @drop.prevent="onDrop" > <i aria-hidden="true" class="fa fa-plus"></i> //+アイコン <div class="drop"> <p class="drag-drop-info">ここにファイルをドロップ</p> <p>または</p> <label for="corporation_file" class="btn btn-success"> ファイルを選択 <input type="file" class="drop__input" style="display:none;" //★⑤ id="corporation_file" @change="onDrop" //★⑥ > </label> {{ fileForm.fileName }} </div> </div> </template> <script> export default { data() { return { isDrag: null } }, methods: { checkDrag(event, key, status){ //★④ if (status && event.dataTransfer.types == "text/plain") { //ファイルではなく、html要素をドラッグしてきた時は処理を中止 return false } this.isDrag = status ? key : null }, } }; |
①ドラックされている間(isDrag == newの時)は、 -drag というクラスをつけます。
これで、CSSで以下のように表示することができてドラック出来ていることがわかりやすいです!
② dragover時に、 -drag クラスをつけ、③dragleave時に外します。
※Vue.jsではイベント名の後に.preventと書くように、しましょう!そのまま、ドラッグ&ドロップをしてしまうと、ブラウザがファイルを表示してしまうので、.preventで、その処理をキャンセルすることができます。
④実際の処理は、 checkDrag メソッドに書きます。ドラッグするアイテムは一つであれば、 isDrag = true にすればいいだけですが、今回は、ドラッグ&ドロップできるアイテムが複数あることを想定して、key名で判定を行うようにしています。
※ドラッグしてきたアイテムが、ファイルではなく、htmlの時を想定し、 event.dataTransfer.types == "text/plain" の時は、処理を行わないようにしています。
⑤デザインの都合上、input type=”file”は、 style="display:none;" し、ラベルで囲みます。これで、「ファイルを選択」ラベルを押したときもファイルアップロードができるようになりますね!!
⑥changeイベントで、ファイルアップロード処理が発火するようにします。
ファイルアップロード機能を作成する
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
methods: { //inputタグとドラッグ&ドロップから呼ばれる onDrop (event, key = '', image = {}) { this.isDrag = null; //★ドラッグ中のクラスを外しておく。 let fileList = event.target.files ? event.target.files : event.dataTransfer.files; //★①ファイル取得 // ファイルが無い時は処理を中止 if(fileList.length == 0){ return false; } let files = []; for(let i = 0; i < fileList.length; i++){ files.push(fileList[i]); } // 今回は1ファイルのみ送ることにする。 let file = files.length > 0 ? files[0] : []; let fd = new FormData(); //★② fd.append('file', file); this.$root.ajax('post', url, fd, (data) => { // 同じファイル名を選択した際にchangeイベントが走るようにvalueを初期化する。//★③ event.target.value = null; // あとは、コールバック処理に色々書く。 }); } } |
①ファイル選択から呼ばれた場合、 event.target.files からファイルを取得でき、ドラッグ&ドロップの場合は、 event.dataTransfer.files で取得することができます。
後は、ajaxで送るようなデータに整形して、Ajaxでファイルアップロードするだけなのですが、以下の2点に注意してください。
1.②送信データはFormDataを使う
2.③このままだと、同じファイル名を選択した際にchangeイベントが走らなくなってしまうので、 event.target.value = null しておきましょう!
—————————
この記事がお役に立てたら、是非シェアをお願いします^^