#概要
BuefyとVeeValidateを組み合わせると、レスポンシブ && バリデーション付きのフォームが爆速で作れるよっていう話です。
#Buefyとは
Buefy は Vue.js と Bulma をベースとした、UIコンポーネントライブラリです。
レスポンシブに対応したボタンや Date picker など、便利なコンポーネントが多数用意されています。
【Buefyのいいところ】
-
軽量
-
配色やレイアウトに Bulma の知識がそのまま使える
-
SCSSの変数を上書きすることでサイトのテーマカラーなどをカスタマイズ可能
#VeeValidateとは
Vue.js をベースとしたフォームバリデーション・フレームワークです。
様々なルールによるバリデーションがこれ一本で簡単にできます。
【VeeValidateのいいところ】
#なぜ Buefy + VeeValidate か
これら2つが補完しあう形で、バリデーションのめんどくささが一挙に解消されるからです。
【普通に作ろうとするとめんどくさい所一覧】
めんどくさい所 | どう解決されるか |
---|---|
チェック用の関数を色々作らなきゃいけない | VeeValidate に一通り用意されてる |
チェックをリアルタイムにやらなきゃいけない | VeeValidate が普通にやってくれる |
エラーメッセージ表示部分を作らなきゃいけない | Buefy の field コンポーネントにメッセージ表示用の属性が用意されているので、別個に作成しなくてOK |
エラー時にフォームの見た目を変更したい | Buefy の field コンポーネントには色やアイコンを設定するための属性が用意されている |
エラー時は値が送信できないようにしたい | エラー判定用の関数がVeeValidateに用意されている |
具体的にどう実装するかは以下で説明していきます。
#インストール
どちらも基本 npm か yarn でインストールしてVue.use()
で登録するだけです。
ただしVeeValidateはデフォルトが英語なので、日本語のメッセージを表示させたい場合はローカライズする必要があります。
ローカライズの方法についてはこちら。
以下はVue CLI を利用した場合の例です。
import Vue from 'vue'
/* Buefy */
import Buefy from 'buefy'
import 'buefy/dist/buefy.css'
/* VeeValidate */
import VeeValidate, { Validator } from'vee-validate'
import ja from 'vee-validate/dist/locale/ja' // ローカライズ用パッケージ
Vue.use(Buefy)
Vue.use(VeeValidate);
Validator.localize('ja', ja); // ローカライズする
// 以下略
#VeeValidateの使い方
本題の実装に入る前に、それぞれのライブラリのおさらいを簡単にします。
まずはVeeValidateから。
メールアドレス:
<input type="text" v-validate="'required|email'" name="email" >
<div>{{ errors.first('email') }}</div>
-
v-validate
属性にチェックしたい内容を「|」区切りで入れます。
例えば上では'required'と'email'を指定しているため、入力が空だったりアドレスの形式がおかしかったりするとエラーになります。 -
エラー情報は全て
errors
に格納され、.first('fieldName')
でエラーメッセージを一つ取り出すことができます。
#Buefyのフォームの書き方
Buefyにはフォーム用のコンポーネント<b-field>
が用意されています。
<b-field
label="メールアドレス"
type="is-danger"
message="これはメッセージです"
>
<b-input type="text"></b-input>
</b-field>
-
label 属性に入れた文字列がそのフォームのラベルとして表示されます。
-
type 属性には、'is-danger', 'is-white'などフォーム色を指定する文字列を入れます。
Bulmaをやってた人ならどういう色があるかすぐに把握できると思います。
また、これらの色は好きにカスタマイズすることが可能です。
#フォームの実装
さてようやく本題のフォームの実装です。
前2節で見てきたように、
① <b-field>
の message 属性にエラーメッセージをバインドし、
② エラーがあるときのみ type 属性に'is-danger'が入るようにする
ことで、良い感じのフォームができあがります。
<b-field
label="メールアドレス"
:type="{'is-danger': errors.has('email')}"
:message="errors.first('email')"
horizontal
>
<b-input
type="text"
name="email"
v-model="email"
v-validate="'required|email'"
data-vv-as="メールアドレス"
></b-input>
</b-field>
-
errors.has('email')
はエラーがあるかどうかをBooleanで返すので、Vue.jsのクラスのバインディングの記法を使って、
:type="{'is-danger': errors.has('email')}"
のように書くことができます。
-
data-vv-as
にはエラーメッセージで表示させたいフィールド名を指定します。これがない場合は以下のように name がそのまま表示されます。
-
horizontal
属性を付与すると、ラベルとフォームが横並びになります。
#エラー発生時の制御
バリデーションをしてもそのまま送信できてしまってはあまり意味がありません。
そのためデータを送信するメソッド内でもバリデーションを行い、処理を制御する必要があります。
そのためにはVeeValidateの$validator.validate()
を用います。
methods: {
/**
* メールアドレスを送信するメソッド
*/
async registerEmail() {
const isValid = await this.$validator.validate()
if(!isValid) return;
// 以下、送信する処理
}
}
$validator.validate()
はバリデーションを行った後、エラーがなかったかどうかをPromise
で返却します。
返り値がPromise
なので async, await を忘れずにつけましょう。
(先述のerrors.has()
もエラーがあるかどうかを返しますが、バリデーションまでは行わないのでここでは不適です)
#終わりに
以上でレスポンシブデザイン&バリデーション付きのフォームが少ない記述量で作成できました。
エラーを表示する部分をゴチャゴチャ作らなくていいのが個人的には一番嬉しいポイントです。