0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

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

Posted at

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

制作にあたって、こちらの記事を参考にさせていただきました。

contact.gif

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

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

こちらの記事

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

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

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

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

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

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

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は下記の記事で詳しく解説しています。

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

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

先ほどと同様にこちらの記事

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

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

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

##参考

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?