前回実装したリアルタイムのバリデーションがいまいち意図した動作にならなかったので作り直してみました。
See the Pen OJVqPjo by YusukeIkeda (@YusukeIkeda) on CodePen.
##watchを使えばよかったみたい
結論から書くと、リアルタイムで入力値を検証するようなフォームを実装する場合はcomputed
ではなくwatch
を使うと良いようです。
computed
を使用して実装しようとすると、初回アクセス時の空白の時の入力値が空なのも監視されてしまいますが、watch
ではうまく動きました。
##HTML・CSS
HTML・CSSについては前回と大きな変更はありません。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Vue.jsによるサンプルバリデーション</title>
<style>
[v-cloak] {
display: none;
}
table td{
width: 200px;
}
table input[type="text"]{
width: 100%;
}
</style>
</head>
<body>
<div id="app">
<div v-cloak>
<p v-show="checkName.valid">{{checkName.error}}</p>
<p v-show="checkTel.valid">{{checkTel.error}}</p>
<p v-show="checkEmail.valid">{{checkEmail.error}}</p>
</div>
<table>
<tr>
<th>名前:</th>
<td><input type="text" v-model="checkName.message" value=""></td>
</tr>
<tr>
<th>電話番号:</th>
<td><input type="text" v-model="checkTel.message" value=""></td>
</tr>
<tr>
<th>メール:</th>
<td><input type="text" v-model="checkEmail.message" value=""></td>
</tr>
</table>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.6/dist/vue.js"></script>
<script src="script.js"></script>
</body>
</html>
##JavaScript
JavaScriptについては先程記述したとおり、Vue.jsのバリデーションはcomputed
ではなくwatch
で値を監視するようにしました。それによって、初回アクセス時に入力が空の時にバリデーションに引っかかる事がなくなりました。ちなみに、初回アクセス時にバリデーションを検知させたい場合はimmediate:true
を指定する必要があります。
また、deep:true
はオブジェクトの内側のネストされたプロパティの変更を監視したい時に設定するもので、handler
はウォッチャがオブジェクト内の変更を感知した際に実行する処理を記載する場所となります。
let validation = (val, type, max) => {
let checkVal = val.message.length;
if(checkVal == 0) {
val.valid = true;
val.error = `${type}は必須です`;
} else if(checkVal > max) {
val.valid = true;
val.error = `${type}は${max}文字以内で入力してください`;
} else {
val.error = "";
val.valid = false;
}
}
let vm = new Vue({
el: '#app',
data: {
checkName: {
message: '',
error: '',
valid: false,
},
checkTel: {
message: '',
error: '',
valid: false,
},
checkEmail: {
message: '',
error: '',
valid: false,
},
},
watch: {
checkName: {
handler(val) {
validation(val, '名前', 10);
},
deep: true
},
checkTel: {
handler(val) {
validation(val, '電話番号', 10);
},
deep: true
},
checkEmail: {
handler(val) {
validation(val, 'メールアドレス', 10);
},
deep: true
},
}
});
#課題とまとめ
実際に運用されているサイトに組み込むには、以下のようなケースも考えて実装する必要がありそうなのでもう少し改良が必要ですが最低限のたたき台はできました。
・すべてのバリデーションを通過したら送信ボタンをアクティブにするような処理。
・正規表現によるバリデーションの実装。
・日付、年齢によるバリデーションの実装。
・電話番号の入力フォームが分割されていた場合の処理。
上に挙げた仕様は頻出するので導入するのであれば事前に実装の方針を考えておいたほうが良さそうです。