Vue.js+Firebaseでメールフォームを作成する

##はじめに
Vue.jsで制作したSPAにFirebaseFunctionsを用いて簡単にメールフォームを設置できました。

制作にあたって、[こちらの記事](https://qiita.com/ryo2132/items/7cdd6c86dd418095f74a)を参考にさせていただきました。

![contact.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1009493/694f7ed1-12a2-9132-0606-1d6b79effd8f.gif)

適用したVue.jsのアプリはこちら↓

https://komekami.info/contact

##1. FirebaseFunctionsの追加とメール通知処理の実装

[こちらの記事](https://qiita.com/ryo2132/items/7cdd6c86dd418095f74a)の

　1. プロジェクトの追加
　2. Firebase functionでのメール通知処理の実装

を参考にさせていただきました。

Functionsを使用するにあたって有料枠にする必要がありますが、従量課金制度なので大量にメールが送られてこない限り、無料で使うことができます。

また、2.のconfig内の値はFirebaseプロジェクトコンソールのcdnチェックボックス内に記載されています。

##2. ContactFormコンポーネントの作成

component配下でContact.vueファイルを作成します。

```vuejs:Contact.vue
<template>
  <div class="contact">
    <h1>Contact</h1>
    <v-container>
      <v-form
        ref="form"
        v-model="contactFormValidation.valid"
        lazy-validation
      >
        <v-text-field
          v-model="contactForm.name"
          :rules="contactFormValidation.nameRules"
          label="name"
          required
        ></v-text-field>
        <v-text-field
          v-model="contactForm.email"
          :rules="contactFormValidation.emailRules"
          label="email"
          required
        ></v-text-field>
        <v-textarea
          v-model="contactForm.contents"
          :rules="contactFormValidation.contentsRules"
          label="contents"
          required
        ></v-textarea>
        <v-btn
          :loading="contactForm.loading"
          :disabled="!contactFormValidation.valid"
          @click="sendMail()"
          color=primary
          block
          large
        >submit
        </v-btn>
      </v-form>
    </v-container>
    <v-snackbar
      v-model="snackBar.show"
      :color="snackBar.color"
      bottom
      right
      :timeout="6000"
    >
    {{snackBar.message}}
    </v-snackbar>
  </div>
</template>

<script>
import { functions } from '@/plugins/firebase.js'
export default {
  data: () => ({
    contactForm: {
      name: '',
      email: '',
      contents: '',
      loading: false
    },
    contactFormValidation: {
      valid: false,
      nameRules: [v => !!v || '必須項目です'],
      emailRules: [
        v => !!v || '必須項目です',
        v => /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(v) || 'メールアドレスが正しくありません'
      ],
      contentsRules: [v => !!v || '必須項目です']
    },
    snackBar: {
      show: false,
      color: '',
      message: ''
    }
  }),
  methods: {
    sendMail: function () {
      if (this.$refs.form.validate()) {
        this.contactForm.loading = true
        const mailer = functions.httpsCallable('sendMail')

        mailer(this.contactForm)
          .then(() => {
            this.formReset()
            this.showSnackBar(
              'success',
              'お問い合わせありがとうございます。送信が完了しました。'
            )
          })
          .catch(err => {
            this.showSnackBar(
              'error',
              '送信に失敗しました。時間をおいて再度お試しください。'
            )
            console.log(err)
          })
          .finally(() => {
            this.contactForm.loading = false
          })
      }
    },
    showSnackBar: function (color, message) {
      this.snackBar.message = message
      this.snackBar.color = color
      this.snackBar.show = true
    },
    formReset: function () {
      this.$refs.form.reset()
    }
  }
}
</script>
```

空欄だったり、メールアドレスが正しくないと送信できないようにvalidationを設けました。

特にメールアドレスのvalidationは下記の記事で詳しく解説しています。

https://qiita.com/komekami0131/items/7a7834ea63eb0f22d161

また、App.vueにContact.vueを読み込ませることも忘れずに行いましょう。

##3. メールサーバの設定・デプロイ

先ほどと同様に[こちらの記事](https://qiita.com/ryo2132/items/7cdd6c86dd418095f74a)の

　4. メールサーバーの設定・デプロイ

を参考にさせていただきました。

##さいごに
Firebaseを使うとサーバサイドの処理をほとんど記述することなく、メールフォームを実装できるので驚きました。
v-modelでの双方向バインディングで入力情報を常にチェックできるのでVue.jsを用いてよかったと思います。

##参考

https://qiita.com/ryo2132/items/7cdd6c86dd418095f74a