ちょこちょこVue.jsを使ってるんですが、まだ手に馴染みません。まだまだ馴染まない理由の1つにフォームがあります。
Railsをメインに使う生活をしているので、form_for
がないとフォームが書けません。というか、simple_form
gemばかり使っているのでさらになまっていて、たとえばbootstrap
のフォームがどんな構造なのかを忘れているので、すごく手間がかかってしまいます。
さて、フォームを組み立てたら次はValidationしたくなります。昔ながらなRailsアプリケーションではフォームの内容をいったんサーバーに送って、サーバーサイドでバリデーションを書けます。
せっかくVue.js使うならクライアントサイドでもそれなりにやってしまったほうが良いですよね(ですよね?)。
VeeValidateというVue.js用のバリデーションライブラリを見つけたので試しました。
VeeValidate用サンプルアプリ
問い合わせフォームっぽいものを作りました。
- メールアドレス
- タイトル
- 本文
を入れてもらうフォームで、全項目必須、メールはフォーマットまで確認するということにしました。
HTML
<div id="app">
<form action="" @submit.prevent="validate">
<div class="form-group">
<label for="">メールアドレス</label>
<input name="email" type="text" class="form-control" v-validate="'required|email'" />
<span class="text-danger">{{ errors.first('email') }}</span>
</div>
<div class="form-group">
<label for="">タイトル</label>
<input name="title" type="text" class="form-control" v-validate="'required'" />
<span class="text-danger">{{ errors.first('title') }}</span>
</div>
<div class="form-group">
<label for="">本文</label>
<textarea rows="5" class="form-control" name="body" v-validate="'required'">
</textarea>
<span class="text-danger">{{ errors.first('body') }}</span>
</div>
<button type="submit" class="btn btn-primary">送信</button>
</form>
</div>
見た目は↓↓な感じね。
JavaScript
JavaScriptはあまり書くことがありません。
VeeValidate
自体の登録- Vueインスタンスの生成
- バリデーション処理
うまくいったときだけalert
が表示されます。実際のアプリケーションではサーバーにPOSTするなど必要な処理を実行することになります。
Vue.use(VeeValidate);
new Vue({
el: '#app',
methods: {
validate() {
this.$validator.validateAll()
.then((result) => {
if (result) {
alert('valid!');
}
});
}
}
});
VeeValidateの使い方
VeeValidateで重要なのことはこの2行を見れば大体わかると言えそうです。
<input name="email" type="text" class="form-control" v-validate="'required|email'" />
<span class="text-danger">{{ errors.first('email') }}</span>
1行目のname=
とv-validate=
、2行目のerrors.first('email')
が重要です。
name
name
かdata-vv-name
がないと警告が出ます。
"[vee-validate] A field is missing a 'name' or 'data-vv-name' attribute"
後述するエラー情報などに使われるからだと考えられます。
v-validate
こちらはバリデーション条件を指定する属性で、文字列やオブジェクトを渡すことができるようです。
必須項目には'required'
、必須かつメールアドレスのフォーマットチェックには'required|email'
のように複数の条件を結合して使えそうです。
ルールの一覧はこちらのドキュメントに。
かなり豊富なので大抵のことは簡単に指定できそう。
さきほどの例では、'required'
と'required|email'
を使っています。
エラー表示
errors.first('email')
には、name="email"
なinputにバリデーションエラーがある場合に、エラーメッセージが入っています。
<span class="text-danger">{{ errors.first('email') }}</span>
として表示するようにしておくと、エラーがあるときだけメッセージが表示されます。
エラーメッセージの日本語化やフォームの見た目調整など気になるところはありますが、ひとまずこれでバリデーションできたと言えそうなところまで来ました。
コード全体
今回のコード全体です。