Edited at

Vue.jsでフォームバリデーションを作ってみよう!


はじめに

こちらはサポーターズColab で開催の勉強会の説明資料です。



この記事に書いてあること



  • VueCLI を使った環境構築の手順

  • コンポーネントの作り方

  • ボタンをクリックしたときのフォームバリデーション実装


この記事で省いていること


  • ツールや構成ファイルの説明

  • コードのリファクタリング



環境


  • 端末


    • Mac OS X 10.14.5



  • インストール済みのライブラリ





開発環境のインストール

Vue.jsの開発環境の構築方法として、下記の2つがあります。



  • script で直接埋め込む


    • 個人開発向け

    • 表示部分を.html.css.jsファイルで作成




  • ‌VueCLI 使ってインストール


    • 中規模以上の開発向け

    • 表示部分を.vueファイルで作成



今回は.vueファイルを使いたいので、‌VueCLIを使っていきます。

インストール手順は、VueCLIの公式サイトにしたがって進めていきます。



vue-cliのインストール

下記コマンドを実行します。


shell

$ npm install -g @vue/cli


インストールが完了すると下記の表示されます。


shell

+ @vue/cli@3.8.2

added 877 packages from 554 contributors in 60.837s



VueCLIの 2.x がインストールされていて、3.xに変更したい方

今のバージョンをアンインストールの上、再度インストールをお願いします。


shell

$ npm uninstall -g vue-cli

$ npm install -g @vue/cli



プロジェクトを作成


shell

$ vue create my-project


my-project の部分はファイル名になります。

自分が管理しやすい名称をつけてください。

※コマンドを実行した際に下記が出てくることがあります。

Your connection to the default npm registry seems to be slow.

Use https://registry.npm.taobao.org for faster installation? (Y/n)

特に急ぎでない場合は n を入力します。



プリセットの選択

Vue CLI v3.2.1

┌───────────────────────────┐
│ Update available: 3.8.2 │
└───────────────────────────┘
? Please pick a preset: (Use arrow keys)
❯ default (babel, eslint)
Manually select features

プリセットに関して今回は default (babel, eslint) を選択します。


パッケージマネージャーの選択

? Pick the package manager to use when installing dependencies: (Use arrow keys)

❯ Use Yarn
Use NPM

特にこだわりがなければ Use NPM を選択します。

※表示されない場合もあります。

インストールが開始され、完了すると、下記が表示されます。

🎉  Successfully created project my-project.



ローカル環境を立ち上げる

インストール完了後に表示されていたコマンドを実行します。

👉  Get started with the following commands:

$ cd my-project
$ npm run serve

立ち上げが成功すると、下記が表示されます。

DONE  Compiled successfully in 3538ms                                0:00:00 PM

App running at:
- Local: http://localhost:8080/
- Network: http://0.0.0.0:8080/

Note that the development build is not optimized.
To create a production build, run npm run build.

http://localhost:8080 にアクセスし、表示ができていれば、環境構築は完了です。



フォームバリデーションを作る

ここから実際の開発を進めていきます。



単一ファイルコンポーネントの記述方法

開発に入る前に単一ファイルコンポーネントの構成について説明します。

単一ファイルコンポーネントは、 <template><script><style> のタグで構成されています。


.vue

<template>

<!-- HTMLの記述はこちら -->
</template>
<script>
export default {
// JavaScriptの記述はこちら
}
</script>
<style scoped>
/* CSSの記述はこちら */
</style>

各タグの役割については下記の通りです。


template

HTMLの記述箇所。

HTMLのテンプレートエンジンのPUGを導入することも可能。


script

JavaScriptの記述箇所。

TypeScirptを導入することも可能。


style

scoped をつけることで、styleをコンポーネント内に閉じ込めることができる。

PostCSSやLess、Sass、Scss、Stylusを導入することも可能。

単一コンポーネントのタグの順序に関しては、公式ガイドの単一ファイルコンポーネントのトップレベルの属性の順序を参照ください。



コンポーネントを作成

src/components/ の配下に LoginForm.vue をファイルを作成し、下記を記述します。


src/components/LoginForm.vue

<template>

<div>
<p><b>{{title}}</b></p>
</div>
</template>

<script>
export default {
props: {
title : String
}
}
</script>

<style scoped>
</style>



template

scriptで宣言した title を表示できるよう記述


script

src/App.vue のテンプレートで src/components/LoginForm.vue を使用するため、App.vueが親、LoginForm.vue が子という関係になります。

Vue.jsは単方向のデータフローのため、親と子の間でデータをやり取りする際には、宣言が必要です。

親から子へデータを渡す際にはpropsを用い、 子から親データを渡すときはカスタムイベントを用います。



App.vueからコンポーネントを使用

‌src/App.vue から src/components/LoginForm.vue を呼び出します。


src/App.vue

<template>

<div id="app">
<img alt="Vue logo" src="./assets/logo.png">
<!-- ここから追加 -->
<hr>
<LoginForm title="ログインフォーム"></LoginForm>
<hr>
<!-- ここまでを追加 -->
<HelloWorld msg="Welcome to Your Vue.js App"/>
</div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'
import LoginForm from './components/LoginForm.vue'// 追加

export default {
name: 'app',
components: {
HelloWorld,
LoginForm // 追加
},
}
</script>

<style>
/* 省略 */
</style>



template

scriptで登録したコンポーネントを LoginForm をタグとして使用します。

titleログインフォームという文字列を親から子に渡しています。


script

componentsのオプション内にLoginFormをコンポーネントとして定義しています。



フォーム入力バインディングを作成

src/components/LoginForm.vue にフォームを作り、入力した値をバインディングする処理を追加します。


src/components/LoginForm.vue

<template>

<div>
<p><b>{{title}}</b></p>
<!-- ここから追加 -->
<form>
<span>ID : </span>
<input
type="text"
placeholder="input your id"
v-model="loginForm.loginId"
>
<p>
Input loginId is {{ loginForm.loginId }}
</p>
</form>
<!-- ここまでを追加 -->
</div>
</template>

<script>
export default {
props: {
title : String
},//ここにカンマを追加
//ここから追加
data: function() {
return {
loginForm:{
loginId:null,
}
}
}
//ここまでを追加
}
</script>

<style scoped>
</style>



templete

データとフォームの入力項目をバインドするため、 v-model を使用しています。

v-modelの詳細は、公式ガイドのv-modelを参照ください。


script

data は、アプリケーションで使用するデータを記述します。



フォームのバリデーションを設定

送信ボタンを押したタイミングでバリデーションをチェックする形のフォームバリデーションを追加します。

下記の2つをエラーが表示される条件として追加します。


  • 値が入力されていない場合

  • 半角英数以外で入力されている場合


src/components/LoginForm.vue

<template>

<div>
<p><b>{{title}}</b></p>
<!-- v-on:submit.prevent="onSubmit" を追加 -->
<form
v-on:submit.prevent="onSubmit"
>
<span>ID : </span>
<input
type="text"
placeholder="input your id"
v-model="loginForm.loginId"
>
<p>
Input loginId is {{ loginForm.loginId }}
</p>
<!-- ここから追加 -->
<p class="error">
{{ Validation.loginReult }}
</p>
<button v-on:click="checkFrom">
送信する
</button>
<!-- ここまでを追加 -->
</form>
</div>
</template>

<script>
export default {
props: {
title : String
},
data: function() {
return {
loginForm:{
loginId:null,
},//ここにカンマを追加
//ここから追加
Validation:{
loginReult: "",
}
//ここまでを追加
}
},//ここにカンマを追加
//ここから追加
methods: {
checkFrom: function(event){
var LoginId = false

//IDの入力フォームのバリデーション
if (!this.loginForm.loginId) {
this.Validation.loginReult="ログインIDを入力してください"
}
else if(!this.checkString(this.loginForm.loginId)){
this.Validation.loginReult="半角英数で入力してください"
}else {
LoginId = true
}

if(LoginId == true){
this.Validation.loginReult=""
alert('Hello,' + this.loginForm.loginId + '!');
}
event.preventDefault()
},
checkString: function(inputdata){
var re = /^[A-Za-z0-9]*$/
return re.test(inputdata);
}
}
//ここまでを追加
}
</script>

<style scoped>
/* ここから追加 */
.error { color: red; }
/* ここまでを追加 */
</style>



template

v-on:submit.prevent="onSubmit" は、submit イベントによってページがリロードされないイベント修飾子です。


script

<script> 内の methods は、アプリケーションで使用するメソッドを指定します。

処理の分割やイベントハンドラなどを記述します。


ここまでの記述を追加し、フォームを空状態、全角文字で入力した状態、半角文字で入力した状態で送信ボタンをクリックして下記の挙動が再現されれば、完成です🎉



追加演習1

src/components/LoginForm.vue にパスワードのフォームを追加し、フォームにバリデーションを設定する


条件


  • フォームタイプは password

  • 未入力時にはエラーを表示

  • 8文字以上かつ英数字記号にもエラーを表示


ヒント

英数字記号の正規表現は下記を使います。


正規表現

/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!-/:-@[-`{-~])[!-~]$/i



回答サンプル

GitHub:matsumana07384/form-validation-of-vue.js-sample


追加演習2


  • フォームの入力中にエラーを表示しよう



その他のオプション

今回は使用していませんが、Vue.jsを理解する上で重要なオプションをご紹介します。


computed

任意のデータを処理を返す算出プロパティ。


watch

特定のデータや算出プロパティの状態を監視して、データの変化をフックとして、処理を実行するプロパティ。



最後に

頑張ってフォームのバリデーションを作りましたが、世の中には簡単にバリデーションを設定できる素晴らしいライブラリがあります。

これらを使えば、よりよいUXのフォームバリデーションをかんたんに開発できます。

よい世の中です。


他にもVue.jsにはたくさんのサポートライブラリがあるため、いろんなことができます。

今回のハンズオンではVue.jsの一部機能にしか触れておりません。

もっと知りたい!と思って頂けた方は、ぜひ公式ガイドを読んだり、コミュニティに参加したりしてみてください!

ここまでご参加頂き、ありがとうございました🙏🏻