当ブログ人気記事!
転職体験談
Laravelで学ぶWebアプリ開発
誰でも作れるチャットアプリ
未経験への勧め

【Laravel初心者向け講座】Vueでのバリデーション実装方法を解説

プログラミング

フロント側(vue)のバリデーションを実装したい!
どんな風に実装するのー?

記事は、こんな悩みに対して書きました。


この記事を書いている私(@Shoot58153748)は、
2020年1月現在メガベンチャーの社内スタートアップの部署でエンジニア(1年目)をしてます。

プログラミング未経験からメガベンチャーへの転職を成功させた経験・ノウハウ
Webエンジニアになってから学んだこと

をブログにまとめています。


前回の記事では、「バックエンド側(Laravel)のバリデーション」を紹介しましたが、

本記事では、「Vueでのバリデーション」にフォーカスしてソースコード付きで解説していきます。

GitHub:
https://github.com/Shuto-san/laravel-vue-docker

スポンサーリンク

そもそもフロント側でのバリデーションは必要?

実際問題、
フロント側でバリデーションをしていなくても

サーバー側でバリデーションができていれば、
致命的な事故にはなりません。

ですが、サイトをきちんと作り込む上では
フロント側でのバリデーションは欠かせないでしょう。


理由としては、
ユーザーに親切なサイトになります

サーバー側でバリデーションに引っかかる度に、画面遷移や更新してしまうと
軽快なサイトに慣れているユーザーにとってはストレスになってしまいます。


また、
フロント側でリクエストデータを制御してあげることで
無駄なリクエストが投げられることもなくなるので、
サーバーとの通信コストも下げることができます



私は、メンターに口酸っぱく

「バリデーションはフロント側とサーバー側両方で必ずやること」

と言われているため、
もうフロント側でバリデーションをいれないと気持ち悪いですw


ということでフロント側(Vue)でバリデーションを実装していきます。
なにやら調べるとバリデーションのライブラリもあったのですが、

可読性、保守性を意識したコーディングの練習もかねて
ライブラリは使わないことにしました。

バリデーション実装(Vue)

まずは画面のソースコードからみてみましょう。

resources/views/tweet/index.blade.php

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Laravel</title>
    <link rel="stylesheet" href="{{ mix('/css/tweet.css') }}">
</head>
<body>
    <div id="tweet">
        <header>
            <div class="contents">
                <section class="submit-form">
                    <input class="form" v-model.trim="tweet" :class="{'is-error': !canSubmit}">
                    <button class="btn" @click="storeTweet" :disabled="!canSubmit">送信</button>
                    <span v-if="!isValidated.tweet" v-text="validationErrorMessage.tweet" :class="{'is-error-message': !isValidated.tweet}"></span>
                </section>
            </div>
        </header>
        <main>
            <div class="contents">
                <ul>
                    @foreach ($tweets as $tweet)
                    <li>{{ $tweet->tweet }}</li>
                    @endforeach
                </ul>
            </div>
        </main>
        <footer>
        </footer>
    </div>
    <script src="{{ mix('js/tweet.js') }}"></script>
</body>
</html>

headerタグ内をみてください。

v-modelで入力内容を変数tweetにバインディングし、
変数を監視することでバリデーションを行います。

以下のVueタグを用いてバリデーション結果を画面に反映していきます。

v-ifでバリデーションメッセージの出し分け
:disabledは、ボタンの表示・非表示を制御
:classは、デザイン(CSS)の出し分け


具体的にバリデーション機能を実装している
JSの実装内容をみていきましょう。

resources/js/tweet.js

require('./csrf.js');

new Vue({
    el: '#tweet',
    data: {
        tweet: '',
        isValidated: {
            tweet: false
        },
        validationConditions: {
            max: 255
        },
        validationErrorMessages: {
            max: "255文字以下で書いてください"
        },
        validationErrorMessage: {
            tweet: null
        },
        canSubmit: false,
    },
    methods: {
        storeTweet() {
            this.preventDoubleClick();

            this.postTweet();
        },

        preventDoubleClick() {
            if (!this.canSubmit) {
                return;
            }
            this.canSubmit = false;
        },

        postTweet() {
            axios.post('/tweet', {
                tweet: this.tweet
            })
            .then(function (response) {
                this.tweet='';
                console.log(response);
            })
            .catch(function (error) {
                console.log(error);
            });
        }
    },
    watch: {
        tweet: function(newTweet, oldTweet) {
            if (this.tweet === '') {
                this.canSubmit = false;
                return;
            }

            if (this.tweet.length > this.validationConditions.max) {
                this.validationErrorMessage.tweet = this.validationErrorMessages.max;
                this.isValidated.tweet = false;
                this.canSubmit = false;
                return;
            }

            this.validationErrorMessage.tweet = null;
            this.isValidated.tweet = true;
            this.canSubmit = true;

            return;
        }
    }
});

仕様を満たすように変数を設計します。

<仕様>
入力フォームが以下の条件を満たす時、枠の色が赤色かつ送信ボタンが非表示に
・空白の場合
・入力されている文字数が255文字以上の場合

<変数の役割>
tweet:入力フォームに入力されている文字を格納
isValidated:バリデーションを通っているかを判断
validationConditions:バリデーションの条件を管理
validationErrorMessages:バリデーションメッセージを管理
validationErrorMessage:画面表示するバリデーションメッセージを格納
canSubmit:送信可否を判断


仮にバリデーションの条件が増えた場合でも、
validationConditionsvalidationErrorMessages
に配列をプッシュすれば、バリデーション内容を管理しやすいです。


バリデーションのロジックは、
watchに実装します。

変数tweetを監視。
変数が変化するごとにイベントが発火するので、
リアルタイムにバリデーションを行うことができます。

バリデーションに引っかかる場合は、リアルタイムにメッセージが表示され、
バリデーションを通る入力内容でのみ、送信ボタンが押せたほうが
ユーザーに優しいですよね^^

あとは、CSSを追加

resources/sass/_tweet_style.scss

.submit-form {

    .is-error {
        border-color: $red;

        &-message {
            color: $red;
        }
    }

}



JSをビルドして、
ローカルサーバー起動して確認します。

npm run dev
php artisan serve


以上で実装終了です!

まとめ

以上、フロント側Vueでの「バリデーション」の解説でした。

ユーザー体験がリッチなWebサイトが増えている昨今、
もはやフロント側もバリデーションをつけるのは、今や必須事項です。

是非とも、サーバー側だけでなくフロント側のバリデーションも
忘れずにいきましょう。


次回は、

「無限スクロール(Vueライブラリ使用)」

を解説します!



それでは、また!!

プログラミング
スポンサーリンク
シェアする
SHOOTをフォローする
WebエンジニアSHOOTのブログ

コメント

タイトルとURLをコピーしました