九保すこひ@フリーランスエンジニア|累計300万PVのブログ運営中
さてさて、最近は少し忙しくなってしまって以前のように前から書き溜めてたネタを少しずつ記事にするということが実行しにくくなっていますが、その反面色々なパッケージを作ることには時間を割くことはできるようになったので、こちらも少しですがこのブログでお知らせしていきたいと考えています。
そして今回GitHub
とnpm
で公開したパッケージは、Vue+axiosでAjax送信のパラメータを簡単に管理できる「v-api-form」です。
ということで今回は公開したてのv-api-form
パッケージの紹介記事を公開します。
※ 開発環境: Vue 2.5
※ 2019/01/10にパッケージを更新し、ファイルの設定方法がnullからFile、もしくはFileListへ変更になりました。
目次
なぜこのパッケージをつくったか
なぜこのパッケージを作ったかというと、もともとVue
を使うと変数のバインディングができるので入力ボックスのデータを簡単に取得することはできますが、それは入力に「ファイル選択」を含んでいない場合です。
つまり、ファイル選択が可能なフォームな場合、送信データは(私の場合だと)FormData
を使いますが、いちいち個別にコードを書くのはめんどうだからです。
さらに、以前からもこのブログで紹介しているLaravel
バリデーションのエラーメッセージは複数であることを想定しているので、「エラー表示は各入力に対してひとつでいい」場合だといちいちループで最初のものだけ取得するコードを書かないといけないため、これもショートカットできたらと考えました。
インストール
npmコマンドで一気にインストールできます。
npm i v-api-form --save
準備
まずは、メインファイルの/dist/v-api-form.js
を読み込みます。
<script src="/PATH/TO/YOUR/FOLDER/v-api-form/dist/v-api-form.js"></script>
この時点でVue
ミックスインがすでに読み込まれていて、data
変数params
とerrors
が使えるようになっています。
そのため、Vueの設定は次のようになります。
new Vue({
el: '#app',
data: {
params: {
email: 'test@example.com',
password: 'passwd',
profile: File, // ファイル選択用(単体)
photos: FileList, // ファイル選択用(複数)
},
ちなみにパラメータは上から、
- メールアドレス
- パスワード
- プロフィール画像(単体ファイル)
- その他の写真(複数ファイル)
になります。
次にHTML内にバインディングしていきましょう。
<!-- 通常の入力 -->
<input type="text" v-model="params.email">
<input type="password" v-model="params.password">
<!-- ファイル選択 -->
<input type="file" v-file-model="params.profile">
<input type="file" v-file-model="params.photos" multiple>
この中で上2つは通常通りのバインディングになるので問題はありませんが、下2つはv-api-form
パッケージの独自ディレクティブv-file-model
です。
これを設定することでファイルが選択されたら自動的にファイル情報を格納し、さらにここの情報を使って後で紹介するパラメータのクリアなどができるようになっています。
なお、mutiple
を使った複数選択にも対応しています。
FormDataを取得する
ではバインディングしたデータを取得してみましょう。
例えば、ボタンをクリックしたらonSubmit()
が実行される場合です。
onSubmit() {
const params = this.getFormData();
axios.post('/YOUR/URL', params)
.then((response) => {
// ..
})
.catch((error) => {
// ..
});
}
params
はデフォルトで設定された変数なのでgetFormData()
を呼ぶだけでFormData
化されたパラメータを取得することができます。
この中には通常のテキストや英数字などのデータだけでなく、選択されたファイルデータも含まれています。
ちなみにFormDataは直接axios
にパラメータとして使うことができます。
なお、入力とは別のデータを追加したい場合もあると思います。
その場合、FormData
にappend()
で追加してもいいですが、次のように第1引数で追加パラメータを指定することもできます。
const params = this.getFormData({ _method: 'PUT' });
エラーをセットする
先ほども書きましたが、Laravel
が返すエラーメッセージは配列となっているので、最初のものだけを取得するにはループしてそれぞれ取得する必要があります。
これをショートカットするために作られたのがsetFormErrors()
です。
やり方は簡単で、axios
が用意してくれているerror
を引数として指定するだけです。
axios.post(url, params)
.then((response) => {
// ..
})
.catch((error) => {
this.setFormErrors(error);
});
これで変数errors
に再構築されたエラーメッセージが格納されるので、this.errors.email
などとしてエラーメッセージを取得することができるようになります。
ただし、私のようにLaravel + axiosを使っていない場合もあると思います。
その場合はgetFormErrors()
をnew Vue()
内で上書きしてください。(error
はsetFormErrors()
で指定されるデータです)
getFormErrors(error) {
// ここでエラーを準備
return errors;
},
各種データをクリア、リセットする
v-api-form
にはパラメータとエラー・データをクリア、もしくはリセットするメソッドがあります。ひとつずつみていきましょう。
パラメータをクリアする
パラメータが全て空白になります。(ただし、ファイル用の変数はFile
もしくはFileList
になります)
this.clearFormParams();
パラメータをリセットする
上の項目との違いは、データが初期値になるかどうかです。
こちらの場合は、データが初期値に戻ります。
this.resetFormParams();
エラーをクリアする
エラーメッセージを全て空白にします。
そのため、Ajax送信の直前でこのメソッドを呼ぶといいでしょう。
this.clearFormErrors();
複数フォームで使うには
先ほどまでの例ではフォームはページにひとつだけしか存在していませんでしたが、状況によってはフォームが複数ある場合もあることでしょう。
その場合はnew Vue()
にbeforeMount
を追加して、setApiFormParams()
で各パラメータを指定してください。
beforeMount() {
this.setApiFormParams([
{
params: 'params',
errors: 'errors'
},
{
params: 'customParams',
errors: 'customErrors'
}
]);
}
この例で言うと、変数params
とcustomPrams
にそれぞれ入力情報が格納され、さらにerrors
とcustomErrors
にそれぞれのエラーが格納されることになります。
名前を指定してデータを管理する
上記のように複数パラメータを用意した場合、その名前を指定して各メソッドを呼び出すことができます。
名前を指定してFormDataを取得する
第2引数で名前の指定ができます。
この場合は、customParams
に格納されているデータをFormData
化して取得することができます。
const params = this.getFormData({}, 'customParams');
名前を指定してエラーをセットする
例えば、customErrors
にエラーを格納したい場合です。
こちらも第2引数へ指定します。
this.setFormErrors(error, 'customParams');
名前を指定してデータをクリア、リセットする
this.clearFormParams('customParams');
this.resetFormParams('customParams');
this.clearFormErrors('customParams');
おわりに
v-api-form
は汎用的に使うことを想定していたため、IE 11での動作確認も行っています。
ただ、やはりというかIE対応するためになかなか時間を使わされました(笑)
少し前にedge
が内部をchrome
化するというニュースがでましたが、開発者からするとそっちじゃなくてIEの方を優先的にお願いできないでしょうか・・・というのが本音だと思います。
もちろん、過去のソフトウェアが動かなくなるパターンもあるのでしょうが、IEのために生産性が低くなっているのはもはや間違いない事実になっているので・・・こうなったら、みんなで「せいのっ!」で利用をやめませんか(説なる願い ^^;)
ではでは〜!