vue.jsでvalidation付きフォームを作った。
#基本機能
・フォームが正しく入力されているかリアルタイムで出る
・送信ボタンを押した時、全フォームが正しく入力されているか判定して処理を分ける
ようにしている。
今はフォームが空か否かで判定しているが、評価項目(文字数制限など)は比較的簡単に追加できる。
#実装方法
validationを行うにはvue-validatorというライブラリを使うことも可能だが、簡単なvalidationだけではわざわざ使うほどでもない。
公式にあるfirebase+vuejsでのexampleを参考に実装した。
今回のソースコード:github
##validationを作る
今回は
- title
- description
- date
- location
からなるフォームを作る。
入力された情報はnewEventに保持する。
それぞれの項目に対し、booleanをもつvalidationを作成する。
data: {
newEvent: {
title: '',
description: '',
date: '',
location: ''
},
validation: {
title: false,
description: false,
date: false,
location: false
}
},
##validationを行うfilterを作る
HTMLソース内でそれぞれの入力にたいして評価を行うfilterを作成する。
今回は空白か否かのみを作成しているが、ここに評価を追加すれば他の評価方法を追加できる。
例えば公式のexampleではemailアドレスになっているか正規表現でチェックをしているし、文字数制限を課すこともできる。
filters: {
titleValidator: {
write: function (val) {
this.validation.title = !!val
return val
}
},
descriptionValidator: {
write: function (val) {
this.validation.description = !!val
return val
}
},
dateValidator: {
write: function (val) {
this.validation.date = !!val
return val
}
},
locationValidator: {
write: function (val) {
this.validation.location = !!val
return val
}
}
},
ちなみに、ソースコード内の
this.validation.title
などは先ほど宣言したdataの中のvalidationの要素である。
filterで評価した結果がvalidationの要素に格納される。
##HTMLソース内で入力項目をfilterに通す
<form id="form" v-on="submit:addEvent">
<p>title:<input v-model="newEvent.title | titleValidator"></p>
<p>description:<input v-model="newEvent.description | descriptionValidator"></p>
<p>data:<input v-model="newEvent.date | dateValidator"></p>
<p>location:<input v-model="newEvent.location | locationValidator"></p>
<input type="submit" value="Add event">
</form>
v-modelは編集可能な要素に対して双方向データバインディングを提供する(参考)
v-model="newEvent.title | titleValidator"
でdataで宣言したnewEvent.titleに対し、filterで作成したtitleValidatorに通す。
titleValidatorの評価結果はdataのvalidation.titleに随時格納される。
##エラーであれば表示する
v-showにbooleanを渡すと、trueの場合のみ表示できるようにできる。
ここに書く要素のvalidationを渡すことで、エラーの場合のみ表示するようにできる。
<ul class="errors">
<li v-show="!validation.title">title cannot be empty.</li>
<li v-show="!validation.description">description cannot be empty.</li>
<li v-show="!validation.date">date cannot be empty.</li>
<li v-show="!validation.location">location cannot be empty.</li>
</ul>
##エラーの有無を常時監視する
入力フォームのvalidationの中に、一つでもfalseがあるか確認するようにする。
常時計算が行われるcomputedにて、booleanを返すisValidを用意しておく。
computed: {
isValid: function () {
var valid = true
for (var key in this.validation) {
if (!this.validation[key]) {
valid = false
}
}
return valid
}
},
validationの全ての要素を確認していって、一つでもfalseが見つかったらをfalseを返す。
methods: {
addEvent: function (e) {
e.preventDefault()
if (this.isValid) {
console.log("success")
}else{
console.log("need edit")
}
},
}
##addボタンが押されたらisValidの値に基づき処理を変える
<form id="form" v-on="submit:addEvent">
<!--中略-->
<input type="submit" value="Add event">
</form>
formにてsubmitが押されたら、addEventメソッドが実行される。
methods: {
addEvent: function (e) {
e.preventDefault()
if (this.isValid) {
console.log("success")
}else{
console.log("need edit")
}
},
}
addEventが実行されたら、if文でisValidを評価して処理を分ける。