0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Vue.jsによるバリデーションのサンプルを作ってみた(2)

Last updated at Posted at 2020-03-31

前回実装したリアルタイムのバリデーションがいまいち意図した動作にならなかったので作り直してみました。

See the Pen OJVqPjo by YusukeIkeda (@YusukeIkeda) on CodePen.

##watchを使えばよかったみたい

結論から書くと、リアルタイムで入力値を検証するようなフォームを実装する場合はcomputedではなくwatchを使うと良いようです。
computedを使用して実装しようとすると、初回アクセス時の空白の時の入力値が空なのも監視されてしまいますが、watchではうまく動きました。

##HTML・CSS

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はウォッチャがオブジェクト内の変更を感知した際に実行する処理を記載する場所となります。

script.js
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
    },
  }
});

#課題とまとめ

実際に運用されているサイトに組み込むには、以下のようなケースも考えて実装する必要がありそうなのでもう少し改良が必要ですが最低限のたたき台はできました。

追加で考える仕様

・すべてのバリデーションを通過したら送信ボタンをアクティブにするような処理。
・正規表現によるバリデーションの実装。
・日付、年齢によるバリデーションの実装。
・電話番号の入力フォームが分割されていた場合の処理。

上に挙げた仕様は頻出するので導入するのであれば事前に実装の方針を考えておいたほうが良さそうです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?