the industrial

ブログと言うより自分のためのメモ以外の何モノでもないです。でも読んでくださってありがとうございます。

VeeValidate でフォームをいい感じにする

VeeValidate とは

baianat.github.io

フォームにバリデーションを掛けてくれる便利なやつ。

例えば、メールアドレス入力欄のバリデーションを

  • メールアドレス形式
  • 入力必須
  • MAX255文字

としてバリデーションしたい場合、このように定義してあげるだけで

          <input
            v-validate="'email|required|max:255'"
            v-model="form.email"
            :class="{'is-error': errors.has('form[email]')}"
            class="form__input"
            type="email"
            name="form[email]"
            data-vv-as="メールアドレス"
            placeholder="例)info@demo.jp"
          >
          <p
            v-show="errors.has('form[email]')"
            class="form__error">
            {{ errors.first('form[email]') }}
          </p>

こんな感じにしてくれる。

メルアドエラー
メルアドエラー

submit ボタンのクリックを抑制する

さて、バリデーションが通らない場合、保存ボタンなどをクリックさせないようにしたい。

例えばこういったフォームがあったとして

お問い合わせフォームNG
お問い合わせフォームNG

お問い合わせ画面
お問い合わせ画面

入力が全てOKだったら「送信ボタン」がクリック出来るように变化させる。

お問い合わせフォームOK
お問い合わせフォームOK

しかし、バリデーションがエラーとなる入力欄が合った場合は「送信ボタン」をクリックさせたくない。

computed にて fields の invalid を参照する

まずボタンに :disabled="invalid" を定義。

<button
  :class="{ 'button--is-arrow': !invalid, 'button--is-disabled': invalid }"
  :disabled="invalid"
  class="button"
  @click="submit()">
  送信
</button>

さらに computed に下記を定義(バリデーションが設定していないフォームがあってもOK)。

  computed: {
    invalid() {
      const that = this
      const _result = Object.keys(this.fields).map(
        key => that.fields[key].invalid
      )
      return _result.includes(true)
    }
  },

これ、もしかしたらもっと良い方法があるかもしれないので、よかったら教えてくださいまし。

フォームを表す fields にはいろいろな状態を管理するフラグがある

baianat.github.io

Vue Devtools

ざっと動作を見てみた。

対象 初期値 フォーカス 入力(エラー) 入力(エラー無し)
changed false false true true
dirty false false true true
invalid true true false true
pending false false false false
pristine true true false false
required true true true true
touched false true true true
untouched true false false false
valid false false true false
validated false false true true

まああまり気にしなくてもいいけど、ココらへんをゴリゴリ使ったフォームってどんなのがあるのか。

結構複雑になりそうなので、できれば簡潔に実装したいところかな。

あと関係ないけど、VeeValidate と↓を連携させるとすごくカッコイイフォームが出来そうね。

vuetifyjs.com