Larevel+vue.js filepondで簡単ファイルアップロード

目次
filepondとは
filepondはファイルのアップロードを行うために利用するJavaScriptライブラリです。ドラッグ&ドロップに対応しておりUI(ユーザインターフェイス)のデザインも優れているのでユーザにとっても使いやすいファイルアップロード機能を実装することができます。
さらにJavaScriptのUIライブラリ/フレームワークに対応したアダプターが提供されているのでnpmでインストールを行うことで本文書で動作確認を行うVue.js以外にもAngular, React, Svelte, jQueryなどでも簡単に利用することができます。フレームワーク/ライブラリを利用しないJavaScriptでも利用可能です。
今回は、Laravel9 + Vue.js環境でのFilePondの設定方法を確認していきます。
公式サイト:filepond

環境の構築
filepondをLaravel+Vue.jsで利用するには環境の構築を行わなければいけません。
環境の構築方法は以下の文書の1.環境の構築と全く同じなので参考にしてください。
filepondの設定
filepondライブラリのインストール
Laravel+Vue.jsの環境構築が完了したらflepondライブラリのインストールを行います。
filepondライブラリのインストール方法については下記の画面のVueのリンクをクリックすることで確認することができます。

npm installコマンドでfilepondライブラリのインストールを行います。
$ npm install vue-filepond filepond --save
filepondライブラリのimportと設定
Laravelにデフォルトで作成されているExampleComponent.vueファイルを使用します。このファイルはwelocome.blade.phpから下記のように読み込まれています。
<div id="app">
<example-component></example-component>
</div>
filepondのimportはscriptタグで行います。
import vueFilePond from 'vue-filepond';
import 'filepond/dist/filepond.min.css';
filepondをコンポーネントとして使用するために下記の設定を行います。
const FilePond = vueFilePond()
export default {
components:{
FilePond
}
}
コンポーネントをtemplateタグの中で設定します。
<h1>FilePond</h1>
<file-pond />
ここまでの設定が完了すると画面中央にDrag & Dropエリアが表示されます。

何か画面に画像をDrag&Dropしてください。下記のように表示されればfilepond側でDrap&Dropしたファイルを受け取っています。

ここまでに記述した内容は下記となります。
<template>
<div class="content">
<h1>FilePond</h1>
<file-pond />
</div>
</template>
<script>
import vueFilePond from 'vue-filepond';
import 'filepond/dist/filepond.min.css';
const FilePond = vueFilePond()
export default {
components:{
FilePond
}
}
</script>
<style>
.content{
margin:5em;
}
</style>
ファイルのアップロード
ファイルのアップロードを行うためには、serverの情報を追加する必要があります。

<file-pond server="http://127.0.0.1:8000/api/fileupload"/>
サーバに送られているか確認するためにapi.webファイルで送られてきたファイルの情報を取得します。
Route::post('fileupload',function(){
dd(request()->all());
});
server後、再度ファイルをDrag&Dropしてください。ファイルのアップロードの進捗状況が表示され、デベロッパーツールのコンソールを確認するとファイルがサーバに送られてきていることを確認することができます。

送られてきているファイル情報は通常のフォームで送られてくる情報と同じなので、下記のようにファイルの保存を行うことができます。
$file_name = request()->filepond->getClientOriginalName();
request()->filepond->storeAs('public/',$file_name);
初期設定ではfilepondという名前で送られてくるので、filepondからファイルの情報を取り出してサーバに保存します。
filepondを使うと簡単にファイルをアップロードすることがわかりました。
ファイルをDrag&Dropした瞬間にサーバへの送信が開始されましたが、サーバへの送信を直後ではなくユーザに任せることも可能です。後ほど説明するinstantUploadというパラメータで設定します。
filepondは画像のプレビューなどさまざまな機能を持っているので、それらの設定方法についてこれから確認を行っていきます。
filepondの各種設定
複数のファイルをアップロード
初期設定では、1つのファイルしかアップロードすることができません。複数ファイルを許可するためには、file-pondタグにallow-multiple=”true”を設定します。
<file-pond server="/api/fileupload" allow-multiple="true" />

複数ファイルをアップデートできてもその数を制限したい場合があります。その場合は、max-filesで設定を行います。max-filesで指定した数以上のファイルは一括アップロードすることができません。
<file-pond server="/api/fileupload" allow-multiple="true" max-files="3"/>
ファイルのアップロードを手動化
初期設定では、ファイルをDrag&Dropするとすぐにサーバへの送信が開始されます。instantUploadをfalseに設定するとサーバへの送信はユーザの判断に任せることができます。
<file-pond server="/api/fileupload" instantUpload="false">
ユーザがアップロードを選択できるボタンが表示されます。ボタンを押すとアップロードが開始されます。

取り消し機能の無効化
filepondは一度アップロードしたファイルを削除する機能を備えています。filepondが取消機能を持っていてもアプリケーション側に対応する機能がなければユーザインターフェース的にも問題なので、取り消し機能を持っていない時はこの機能を無効にします。
<file-pond server="/api/fileupload" allowRevert="false">
allowRevertをfalseにするとファイルアップロード後に表示されていた取り消しボタンが消えてチェックに変わります。

filepondのプラグイン
filepondはプラグインを使用して機能の拡張を行うことができます。プラグインの名前はfilepond-plugin-プラグイン名になります。
画像プレビュー機能(image-preview)
drag&dropしたファイルの画像をプレビューする機能を追加するためにはimage-previewプラグインをインストールする必要があります。
$ npm install filepond-plugin-image-preview --save
+ filepond-plugin-image-preview@4.2.1
added 1 package from 1 contributor and audited 16939 packages in 11.552s
found 0 vulnerabilities
インストールしたimage-previewとcssをimportし、vueFilePondの引数にFilePondPluginImagePreviewを追加するだけで画像プレビュー機能を使えるようになります。
import vueFilePond from 'vue-filepond';
import 'filepond/dist/filepond.min.css';
/* Plugin */
import FilePondPluginImagePreview from 'filepond-plugin-image-preview';
import 'filepond-plugin-image-preview/dist/filepond-plugin-image-preview.css';
const FilePond = vueFilePond(FilePondPluginImagePreview)
ファイル2つアップロードすると下記のように画像のプレビューが表示されます。

サイズチェックプラグイン(file-validate-size)
アップロードするファイルのサイズでValidationを行うためには、file-validate-sizeプラグインをインストールする必要があります。
$ npm install filepond-plugin-file-validate-size --save
+ filepond-plugin-file-validate-size@2.1.3
added 1 package from 1 contributor and audited 16940 packages in 13.328s
found 0 vulnerabilities
インストール後はmaxFileSizeを使用してvalidationを行うことができます。
<file-pond server="/api/fileupload" maxFileSize="10KB" >
もし設定したサイズよりも大きい場合は、File is too largeのメッセージが表示されます。
