フロント側(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
:送信可否を判断
仮にバリデーションの条件が増えた場合でも、validationConditions
とvalidationErrorMessages
に配列をプッシュすれば、バリデーション内容を管理しやすいです。
バリデーションのロジックは、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ライブラリ使用)」
を解説します!
それでは、また!!
コメント