Nuxt.jsでフロント側でフォームにバリデーションをつけよう！

#  概要
Nuxt.jsを使用しformにフロント側でバリデーションをつけていきます。

## 前提知識
html, css, Vue.jsの基本的な知識
##  プロジェクトの作成
今回はデスクトップに作成していきます

```
cd ~/Desctop
npx create-nuxt-app validate
npm run dev
```

![スクリーンショット 2021-03-21 11.22.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/825833/5929d2c8-fdc0-7d54-18bd-0070ee7e1b8c.png)


こちらが立ち上げれば環境構築は成功です。

```
 touch pages/form.vue
```

今回は以下のようなフォームを作成していきます。

| 項目 | バリデーション | バリデーション |
| ---- | ---- | ---- |
| 名前　| 必ず必要 | 8文字以内 |
| 会社名　| 必ず必要 |　  |

```pages/form.vue
<template>
  <form>
    <label>名前</label>
    <input type="text" v-model="form.name.val">
    <p>{{form.name.val}}</p>
    <label>会社名</label>
    <input type="text" v-model="form.company.val">
  </form>
</template>

<script>
export default {
  data() {
    return {
      form: {
        name: {
          label: "名前",
          val: null,
          errorMessage: null
        },
        company: {
          label: "会社名",
          val: null,
          errorMessage: null
        },
      },
    }
  },
}
</script>

```
まずはこんな感じに簡単に記述していきます。
説明するとまずは適当にフォームを作成します。
scriptタグの中身は
dataでformのデータを作成し、その中にnameとcompanyを作っています。

v-modelでそれぞれの入力された値を受け取っています。
labelはそれぞれのinputの名前を選択しておきます。
valとerrorMessageを作成しデフォルト値をnullにします。

 
## バリデーションを追加していく
バリデーションのメソッドを追加していきます。

```pages/form.vue
<script>
export default {
  data() {
    return {
      form: {
        name: {
          label: "名前",
          val: null,
          errorMessage: null
        },
        company: {
          label: "会社名",
          val: null,
          errorMessage: null
        },
      },
    }
  },
  methods: {
    validateName() {
      const { name } = this.form
      const maxLength = 8

      if(!name.val) {
        name.errorMessage = `${name.label}は必須項目です`
        return
      }

      if (name.val.length > maxLength) {
        name.errorMessage = `${name.label}は${maxLength}以内で入力してください`
        return
      }
      name.errorMessage = null
    },
    validateCompany() {
      const { company } = this.form

      if (!company.val) {
        company.errorMessage = `${company.label}は必須項目です`
        return
      }
      company.errorMessage = null
    },
    onSubmit() {
      this.validateName()
      this.validateCompany()
    }
  }
}
</script>
```
scriptタグをこちらに変更します！
説明します。
バリデーションを
validateName, validateCompanyメソッドで追加してます。

const {name} = this.formでまず代入をし
8文字以内の設定なのでmaxLengthを8に設定します。
あとはif分で条件を出していくだけなのですが、`${}`のテンプレートリテラルを利用して条件に一致すればnullのエラ〜メッセージを書き換えていきます。
必ずreturnで処理を終わらせるのを忘れずに！

最後にonSubmitでこれらのメソッドを呼び出します。
あとはどのタイミングでエラ〜メッセージを出すか自分で決めるだけです。

## エラ〜メッセージを反応させる
今回はエラ〜メッセージを出すをゴールにしているので、デザインはほぼ行いません。

```pages/form.vue
<template>
<div>
  <form @submit.prevent="onSubmit">
    <label>名前</label>
    <input @keyup="validateName" :class="{'border-red':form.name.errorMessage}" type="text" v-model="form.name.val">
    <label>会社名</label>
    <input @keyup="validateCompany" :class="{'border-red':form.company.errorMessage}" type="text" v-model="form.company.val">
    <input type="submit">
  </form>
  <p class="errorMessage">{{form.name.errorMessage}}</p>
  <p class="errorMessage">{{form.company.errorMessage}}</p>
</div>
</template>

<script>
export default {
  data() {
    return {
      form: {
        name: {
          label: "名前",
          val: null,
          errorMessage: null
        },
        company: {
          label: "会社名",
          val: null,
          errorMessage: null
        },
      },
    }
  },
  methods: {
    validateName() {
      const { name } = this.form
      const maxLength = 8

      if(!name.val) {
        name.errorMessage = `${name.label}は必須項目です`
        return
      }

      if (name.val.length > maxLength) {
        name.errorMessage = `${name.label}は${maxLength}以内で入力してください`
        return
      }
      name.errorMessage = null
    },
    validateCompany() {
      const { company } = this.form

      if (!company.val) {
        company.errorMessage = `${company.label}は必須項目です`
        return
      }
      company.errorMessage = null
    },
    onSubmit() {
      this.validateName()
      this.validateCompany()
    }
  }
}
</script>

<style>
.errorMessage {
  color: red;
}
.border-red {
  border: 1px solid red;
}
</style>
```
こちら最終的なコードです。

注目すべき点だけ説明していきます。
@submit.prevent="onSubmit"でまずバリデーションを呼び出します。
@submithじゃv-on:submitの省略記法で、つまりフォームを送信するタイミングでバリデーションを確認して！
といった意味になります。
preventはsubmitのイベント修飾子でsubmitの動きを止めることができます。
エラ〜メッセージが出たのに、送信されたら意味がないですからね笑

submit.preventはよく使うので覚えておきましょう。

あとは@keyupのタイミングでそれぞれのバリデーションを確認しています。
:classはv-bind:classの省略記法で
{クラス : A}
Aがtrueであればクラスを適用するといった意味になります。

つまりエラ〜メッセージがあればstyeleを適用するですね。
border: 1px solid redが適用されます。

![スクリーンショット 2021-03-21 17.43.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/825833/5f0b9574-350f-d7f2-42db-92a0425c413c.png)

![スクリーンショット 2021-03-21 17.43.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/825833/f4aca609-b0ac-6dcc-5c40-018846513466.png)

お疲れ様でした！！