vee-validateでカスタムルール(住所)

## 概要
住所のようにすべての項目を入力してほしい場合の独自ルールを作ってみる。

## 実装方法
下記のやり方でうまくいったので、添付しておく。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Validation</title>
</head>
<body>

  <div id="app">
    <h1>Vee-Validate(独自ルール - 住所)</h1>

    <div>
      <label>住所</label>
      <div :class="{'is-error': errors.has('last_name') }">
        <input type="text" name="prefecture" v-model="prefecture">(都道府県)<br>
        <input type="text" name="city" v-model="city">(市区町村)<br>
        <input type="text" name="street" v-model="street">(番地など)
      </div>
      <div v-show="errors.has('address')">
        <p>{{ errors.first('address') }}</p>
      </div>
    </div>

    <button type="button" @click="submit">作成する</button>

    <div v-show="errors.has('notification')">
      <p>{{ errors.first('notification') }}</p>
    </div>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2.5.13"></script>
  <script src="https://cdn.jsdelivr.net/npm/vee-validate@2.1.0-beta.9/dist/vee-validate.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/vee-validate@2.1.0-beta.9/dist/locale/ja.js"></script>
  <script>
    Vue.use(VeeValidate);

    new Vue({
      el: '#app',
      // データ
      data: {
        prefecture: null,
        city: null,
        street: null,
      },
      created() {
        // メッセージを日本語に設定する
        this.$validator.localize('ja');

        /**
         * 入力検証 (住所 - 都道府県 / 市区町村 / 番地など)
         *
         * ※ 都道府県 / 市区町村 / 番地 の3つとも選択する
         */
        this.$validator.extend('address', {
          current: null,
          getMessage(field) {
            if (!this.current.prefecture)
              return "都道府県を選択してください";
            if (!this.current.city)
              return "市区町村を入力してください";
            if (!this.current.street)
              return "番地を入力してください";
          },
          validate(value) {
            this.current = value;
            if (!value.prefecture || !value.city || !value.street) {
              return false;
            }
            return true;
          }
        });
        this.$validator.attach({
          name : "address",
          alias: '住所',
          rules: "address",
          getter: () => this.address
        });
      },
      computed: {
        address() {
          return {
            prefecture: this.prefecture,
            city      : this.city,
            street    : this.street,
          };
        }
      },
      watch: {
        address(value) {
          this.$validator.validate('address', value);
        }
      },
      methods: {
        submit: function () {
          // お知らせメッセージを初期化
          this.$validator.errors.remove('notification');

          // バリデートの判定
          this.$validator.validateAll().then((result) => {

            if (result === false) {
              // 入力エラー
              this.$validator.errors.add({field: 'notification', msg: '入力エラーがあります...'});
              return false;
            }

            // 何かしらの処理...
            const is_success = (Math.random() > 0.3);
            if (!is_success) {
              // お知らせメッセージをセットする
              this.$validator.errors.add({field: 'notification', msg: '処理に失敗しました...'});
              return false;
            }

            //エラーがなかった時の処理を下に記述
            alert('Submit OK.')
          });
        }
      }
    });
  </script>
</body>
</html>
```
## 実行結果
作成ボタンを押すと、エラーメッセージが表示されました。
![test.png](https://qiita-image-store.s3.amazonaws.com/0/142279/674f6ea5-e8b8-796e-aeb1-ecb2fed095ae.png)

## まとめ
「computed」を経由して処理するのが悩ましい...

## 参考サイト
- [VeeValidate - Custom Rules](https://baianat.github.io/vee-validate/guide/custom-rules.html#creating-a-custom-rule)
- [validateAll() not running on validations attached in child component](https://github.com/baianat/vee-validate/issues/974)
- [VeeValidateで複数のフィールドにバリデーションをかけるやり方](https://qiita.com/_Keitaro_/items/c06210d69f8c8382dfab)
- [Vee-validate : how to attach several validation rules after object constructed](https://stackoverflow.com/questions/50050515/vee-validate-how-to-attach-several-validation-rules-after-object-constructed)
- [VeeValidate を使って、vue.jsで簡単にバリデートしてみた](https://qiita.com/youdie/items/417ed2df1bcb6a60001c)