24
23

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 5 years have passed since last update.

Buefy と VeeValidate でお手軽フォームバリデーション!

Last updated at Posted at 2019-05-05

#概要
BuefyとVeeValidateを組み合わせると、レスポンシブ && バリデーション付きのフォームが爆速で作れるよっていう話です。

#Buefyとは

buefy.1d65c18.png

Buefy は Vue.js と Bulma をベースとした、UIコンポーネントライブラリです。

レスポンシブに対応したボタンDate picker など、便利なコンポーネントが多数用意されています。

【Buefyのいいところ】

  • 軽量

  • 配色やレイアウトに Bulma の知識がそのまま使える

  • SCSSの変数を上書きすることでサイトのテーマカラーなどをカスタマイズ可能

#VeeValidateとは

logo.png

Vue.js をベースとしたフォームバリデーション・フレームワークです。

様々なルールによるバリデーションがこれ一本で簡単にできます。

【VeeValidateのいいところ】

  • ルールが豊富に用意されている

  • 自分でカスタムルールを作ることもできる

  • バリデーションだけではなくエラーメッセージの表示やエラー時の挙動なども色々制御できる

#なぜ Buefy + VeeValidate か

これら2つが補完しあう形で、バリデーションのめんどくささが一挙に解消されるからです。

【普通に作ろうとするとめんどくさい所一覧】

めんどくさい所 どう解決されるか
チェック用の関数を色々作らなきゃいけない VeeValidate に一通り用意されてる
チェックをリアルタイムにやらなきゃいけない VeeValidate が普通にやってくれる
エラーメッセージ表示部分を作らなきゃいけない Buefy の field コンポーネントにメッセージ表示用の属性が用意されているので、別個に作成しなくてOK
エラー時にフォームの見た目を変更したい Buefy の field コンポーネントには色やアイコンを設定するための属性が用意されている
エラー時は値が送信できないようにしたい エラー判定用の関数がVeeValidateに用意されている

具体的にどう実装するかは以下で説明していきます。

#インストール

どちらも基本 npm か yarn でインストールしてVue.use()で登録するだけです。

Buefyのインストール

VeeValidateのインストール

ただしVeeValidateはデフォルトが英語なので、日本語のメッセージを表示させたい場合はローカライズする必要があります。
ローカライズの方法についてはこちら。

以下はVue CLI を利用した場合の例です。

main.js

import Vue from 'vue'

/* Buefy */
import Buefy from 'buefy'
import 'buefy/dist/buefy.css'

/* VeeValidate */
import VeeValidate, { Validator } from'vee-validate'
import ja from 'vee-validate/dist/locale/ja' // ローカライズ用パッケージ

Vue.use(Buefy)
Vue.use(VeeValidate);
Validator.localize('ja', ja); // ローカライズする

// 以下略

#VeeValidateの使い方
本題の実装に入る前に、それぞれのライブラリのおさらいを簡単にします。

まずはVeeValidateから。

VeeValidate
メールアドレス:
<input type="text" v-validate="'required|email'" name="email" >
<div>{{ errors.first('email') }}</div>

無題.png

  • v-validate属性にチェックしたい内容を「|」区切りで入れます。
    例えば上では'required'と'email'を指定しているため、入力が空だったりアドレスの形式がおかしかったりするとエラーになります。

  • エラー情報は全てerrorsに格納され、.first('fieldName')でエラーメッセージを一つ取り出すことができます。

#Buefyのフォームの書き方

Buefyにはフォーム用のコンポーネント<b-field>が用意されています。

Buefy
<b-field
    label="メールアドレス"
    type="is-danger"
    message="これはメッセージです"
>
    <b-input type="text"></b-input>
</b-field>

hshsrfhr.png

  • label 属性に入れた文字列がそのフォームのラベルとして表示されます。

  • type 属性には、'is-danger', 'is-white'などフォーム色を指定する文字列を入れます。
    Bulmaをやってた人ならどういう色があるかすぐに把握できると思います。
    また、これらの色は好きにカスタマイズすることが可能です。

#フォームの実装

さてようやく本題のフォームの実装です。

前2節で見てきたように、

<b-field>の message 属性にエラーメッセージをバインドし、
② エラーがあるときのみ type 属性に'is-danger'が入るようにする

ことで、良い感じのフォームができあがります。

<b-field 
    label="メールアドレス"
    :type="{'is-danger': errors.has('email')}"
    :message="errors.first('email')"
    horizontal
>
    <b-input 
        type="text"
        name="email" 
        v-model="email"
        v-validate="'required|email'" 
        data-vv-as="メールアドレス"                
    ></b-input>
</b-field>

haddb.png

:type="{'is-danger': errors.has('email')}"

のように書くことができます。

  • data-vv-asにはエラーメッセージで表示させたいフィールド名を指定します。これがない場合は以下のように name がそのまま表示されます。

ggggggggg.png

  • horizontal属性を付与すると、ラベルとフォームが横並びになります。

#エラー発生時の制御

バリデーションをしてもそのまま送信できてしまってはあまり意味がありません。
そのためデータを送信するメソッド内でもバリデーションを行い、処理を制御する必要があります。

そのためにはVeeValidateの$validator.validate()を用います。

methods: {
    /**
     * メールアドレスを送信するメソッド
     */
    async registerEmail() {
        const isValid = await this.$validator.validate()
        if(!isValid) return;

        // 以下、送信する処理
    }
}

$validator.validate()はバリデーションを行った後、エラーがなかったかどうかをPromiseで返却します。

返り値がPromiseなので async, await を忘れずにつけましょう。

(先述のerrors.has()もエラーがあるかどうかを返しますが、バリデーションまでは行わないのでここでは不適です)

#終わりに
以上でレスポンシブデザイン&バリデーション付きのフォームが少ない記述量で作成できました。

エラーを表示する部分をゴチャゴチャ作らなくていいのが個人的には一番嬉しいポイントです。

24
23
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
24
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?