vuejs メールフォームにVue.jsで送信機能をつけてみよう
» STARTOUT詳細はこちら

WEBサービスづくり学習「STARTOUT」はじめました!

自分の「WEBサービス」を作りながら「制作技術」を習得しよう!

STARTOUTとは、WEB制作×サービス作りのオンライン実践学習サービスです。ゼロからWEBサービスを作り、収益化しながら技術を習得してみましょう!

 詳しくはこちら
ここでは「WEB制作×事業づくり実践学習サービス STARTOUT」の学習コンテンツの一部を公開しています。もし1,000以上あるすべてのコンテンツを学び尽くしたい場合、ぜひこちらからご登録ください!

メールフォームにVue.jsで送信機能をつけてみよう

Vue.js|2019年02月26日

2019年02月26日
  • このエントリーをはてなブックマークに追加

今回の項目を学ぶ前にHTML×CSSでメールフォームのコーディングを学びましょう。
コーディングしたデータに対し、送信機能をつけていくとスムーズです。

メールフォームはWEBサイトやWEBサービスまで、何にでも活用できます。

例えば、お問い合わせフォームのように、連絡を取る方法として。
または会員登録をした時に送られる、自動完了メールとして。

少しずつメールの使用頻度は減っていますが、まだ不要ではありませせん。
仕事として、サービスの連絡事項を伝える方法として、まだまだ使われます。

そこで、今回はメールフォームを作る方法を習得してみましょう。

ただし、メールフォームを作るためには、Vue.jsだけではできません。
HTMLやCSSの知識はもちろん、バックエンド言語の知識も必要となります。

メールはサーバーの機能を使って送ります。
サーバーの機能を使うためには、バックエンド側の知識が必要です。

今回、バックエンドの言語はPHPを使っていきます。
PHPの項目を学んでから、取り組むと学びやすくなります。

ただ、絶対ではありませんので、そのまま進んでもOKです。

では、さっそく今回のミッションに進んでいきましょう。
他の言語も混ざってきますし、難易度が少しあがります。

今回のミッション

メールフォームの送信機能まで再現してみましょう。
HTMLやCSSはこちらを参考に作ってみてください。
すでに作られた方は、そのままファイルを使ってもOKです。

再現するファイルは下記になります。

ソースコードの解説を参考に、上記を再現してみてください。

一通りソースコードを理解してから取り組むと良いでしょう。
新しい書き方も出てくるので、いきなりだと難しいかもしれません。

どうしても動かなければ、下記からファイルをダウンロードしてください。
細かい箇所のチェックはエラーなど、見つけてみましょう。

なお、毎回ご提供するこちらはあくまでも、参考ファイルです。
より良い書き方を見つけたら、ご自身で改良してみてください。

ソースコードの解説

まずは、下記ソースコードに目を通してみましょう。
全体の流れを把握したら、すぐに自分で実践してみてください。
処理の概要は以下の通りです。

  1. フォームに入力された内容をリアルタイムでvueのdateに送る
  2. 受け取った値を、リアルタイムでバリデーションチェック(computed)
  3. 確認ボタンを押すと、確認用HTMLに切り替え(methods)
  4. エラーがない状態で、送信ボタンを押すと、axiosというphpと連動する機能で送信

今回はVueからPHPにデータを送信するためにaxiosを使う必要があります。
まずはheadで下記のライブラリを読み込んでみましょう。

index.html

<!--phpにvueからデータを送る機能を付与するaxiosを読み込みます。-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
<!--Vue.jsを読み込みます-->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>

動かす基本環境はこれでOKです。
実際にソースコードを書いていきましょう。
まずはHTMLから解説していきます。

<div class="profBox" id="formarea">
    <h1>メールフォーム</h1>
    <dl>
        <dt>メールアドレス※</dt>
        <dd>
            <!--v-bind:classでクラスをつけたり消したりできます。-->
            <!--inputdataの中身がtrueであれば、クラスdelateareaが付与されます。-->
            <!--delateareaはposishonにより画面外に移動させることで対象要素を消します。-->
            <!--下記は、入力フォームエリアです。-->
            <div v-bind:class="{ delatearea: inputdata }">
                <input type="text" name="namedata"  placeholder="info@startout.work" class="inputText mailarea" v-model="mailarea" />
            </div>
            <!--下記は、入力内容の確認エリアです。-->
            <!--makesureの中身がtrueであれば、クラスdelateareaが付与されます。-->
            <!--{{mailarea}}がv-modelで上記のinputと連動しています。-->
            <!--{{mailarea}}にv-model="mailarea"で入力された箇所がリアルタイムで反映されます。-->
            <div v-bind:class="{ delatearea: makesure }">{{mailarea}}</div>
            <p class="erroebox">{{mailmiss}}</p>
        </dd>
    </dl>
    <!--以降、メールアドレスの時と同じように処理しています。-->
    <dl>
        <dt>お名前※</dt>
        <dd>
            <div v-bind:class="{ delatearea: inputdata }">
                <input type="text" name="namedata"  placeholder="例) 佐々木 太郎" class="inputText namearea" v-model="namearea" />
            </div>
            <div v-bind:class="{ delatearea: makesure }">{{namearea}}</div>
            <p class="erroebox">{{namemiss}}</p>
        </dd>
    </dl>
    <dl>
        <dt>テキストボックス</dt>
        <dd>
            <div v-bind:class="{ delatearea: inputdata }">
                <textarea name="textboxdata" class="textboxdata textboxarea" v-model="textboxarea"></textarea>
            </div>
            <div v-bind:class="{ delatearea: makesure }">
                {{textboxarea}}
            </div>
        </dd>
    </dl> 
    <div v-bind:class="{ delatearea: inputdata }">
        <!--v-on:click="clickbtn"でmethodのclickbtnを起動させます。-->
        <button class="btnStyle1 submitarea" v-on:click="clickbtn">確認</button>
    </div>    
    <div v-bind:class="{ delatearea: makesure }">
        <!--v-on:click="clickbtn_back"でmethodのclickbtn_backを起動させます。-->
        <button class="btnStyle1 submitarea mgb10px" v-on:click="clickbtn_back">戻る</button>
        <!--v-on:click="clickbtn_send"でmethodのclickbtn_sendを起動させます。-->
        <button class="btnStyle1 submitarea" v-on:click="clickbtn_send">送信</button>
    </div>
</div>

なんとなく構造はご理解いただけたでしょうか。
これまで学んできたv-onやv-modelなどを、使いこなす必要があります。

ただ、これだけだと何のことか分からないかもしれません。

jsと組みあわせて見て、初めて意味がわかってくるはずです。
さっそく、jsを見ていきましょう。

<script>
    //下記の変数はエラーがあるとtrueに変わります。
    //どうやって変わるのかは以降の処理でご確認ください。
    //true = ミスがある false = ミスが無い
    //後半でエラーが無いか判断する時に使います。
    var mailerrorbox = "true";
    var nameerrorbox = "true";
     
    var formarea = new Vue({
        el: '#formarea',
        data: {
            //v-modelの値がリアルタイムで反映されます。
            mailarea: "",
            namearea: "",
            textboxarea: "",
            //下記は「入力フォーム」と「確認用文字列」の表示項目を切り替えます。
            //trueとなっている項目は消えます。
            //v-bind:classでclassをつけたり消したりできます。
            //display:none;が設定されたclass(今回はdelatearea)がついたり消えたりします。
            //trueになった方が消えるのは、delateareaがtrueで付与されるためです。
            inputdata:false,
            makesure:true
        },
        computed:{
            //dataの値に変化があると、computedが機能します。
            //入力内容にミスが無いか確認する「バリデーションチェック」を行います。
            mailmiss: function () {
                //変数maildataの中にdataのmailareaの値を入力します。
                let maildata = this.mailarea
                //冒頭のmailerrorboxがここで使われます。
                //まず、mailareaに変更があった時に値をtrueにリセット。
                //次の処理でエラーがなかった場合にfalseになります。
                mailerrorbox = "true";
                //以降、if文でエラーチェックをします。
                if(!maildata){
                    //もし、maildataに何も入っていなかったら、下記のメッセージがmailmissに入ります。
                    //mailmissは{{mailmiss}}で出力できます。
                    return "メールが入ってないよ";
                }else if(maildata.match(/.+@.+\..+/)==null){
                    //もし、maildataに入力された内容がメールアドレスじゃなければ、下記のメッセージ。
                    //「/.+@.+\..+/」は正規表現と言われ、これでメールアドレスの形を確認しています。
                    return "メールの形式間違ってるよ";
                }else{
                    //もし、特にミスがなければ、falseになります。
                    //確認項目がすべてfalseの場合にのみ、メールが送信されます。
                    mailerrorbox = "false";
                };
            },
            //次は、名前のバリデーションチェックです。
            //名前は簡単で、未入力でなければfalseになります。
            //基本的にはメールチェックと同じです。
            namemiss: function () {
                //変数namedataの中にdataのmailareaの値を入力します。
                let namedata = this.namearea
                //エラー有無には冒頭で指定したnameerrorboxが使われています。
                nameerrorbox = "true";
                //以降、if文でエラーチェックをします。
                if(!namedata){
                    //もし、namedataに何も入っていなかったら、下記のメッセージがnamemissに入ります。
                    //namemissは{{namemiss}}で出力できます。
                    return "名前が入ってないよ";
                }else{
                    //もし、特にミスがなければ、falseになります。
                    //確認項目がすべてfalseの場合にのみ、メールが送信されます。
                    nameerrorbox = "false";
                }
            }
        },
        methods:{
            //methodで送信ボタンがクリックされた時の処理を書きます。
            //まず、確認ボタンが押された時からです。
            clickbtn: function () {
                //dataのinputdataにtrueを代入します。
                //するとhtmlのv-bind:classが指定された箇所でdelateareaが付与されます。
                this.inputdata = true
                //dataのmakesureにfalseを代入します。
                //するとhtmlのv-bind:classが指定された箇所でdelateareaが解除されます。
                this.makesure = false
                //上記だと、該当箇所の入力フォームが消えて、確認項目が表示されます。
            },
            //確認画面になった時、戻るボタンを押し、入力画面に戻る時の処理です。
            clickbtn_back: function () {
                this.inputdata = false
                this.makesure = true
                //上記だと、該当箇所の入力フォームが消えて、確認項目が表示されます。
            },
            //送信ボタンを押した時の処理です。
            clickbtn_send: function () {
                //mailerrorboxとnameerrorboxがそれぞれfalseであれば、エラー無しと判断。
                if(mailerrorbox == "false" && nameerrorbox == "false"){
                    //axiosという機能を使ってPHPファイルにデータを送信します。
                    //メールはPHPなどのバックエンド側の言語でしか送れません。
                    //よって、Vue.jsからPHPにデータを渡す必要があります。
                    //下記はデータをPHPに投げる時の1セットだと思ってください。
                    let params = new URLSearchParams();
                    //mailareaという箱の中にdata、mailareに入力された内容を入れます。
                    params.append('mailarea', this.mailarea);
                    //nameareaという箱の中にdata、nameareaに入力された内容を入れます。
                    params.append('namearea', this.namearea);
                    //textboxareaという箱の中にdata、textboxareaに入力された内容を入れます。
                    params.append('textboxarea', this.textboxarea);
                    //axiosという機能を使いデータを投げます。
                    axios.post('functions/mail.php', params)
                    //PHPで処理された結果がresponseに帰ってきます。
                    .then(function (response) {
                        //PHPで処理された結果はresponse.dataで呼び出せます。
                        //今回は、送信完了メッセージが入っています。
                        //詳しくはPHPファイルを確認してみてください。
                        //alertで送信完了メッセージを出します。
                        alert(response.data)
                        //フォームのトップページにリダイレクトします。
                        document.location = "./"
                    })
                    .catch(function (error) {
                        //何かエラーが起きたらconsole.logにエラーを表示させます。
                        console.log("error");
                    })
                };
            }
        }
    })  
</script>

少し長くなりました。

書き方は色々あると思いますが、1つ1つ確認してみてください。
じっくりと1行ずつ、意味とHTMLとの関連性を把握しましょう。
Vue.jsはリアクティブなので、その構造を活用しています。

特にv-modelを活用して、リアルタイムでエラーをチェックするのはVue的でもあります。
jQueryなどでは、いちいちフォーム内容の変化なども処理を書く必要がありました。
そうした手間が省けるのは、Vueの非常に優れているところですね。

なお、表示を切り替えるためのdelateareaというクラスがありました。
delateareaは下記のような内容になっています。

.delatearea{
position: absolute;
left: -9999px;
}

display:none;等で消すのではなく、画面外に吹き飛ばしています。

なぜかと言うと、display:none;にすると、リアクティブに値を入力できないからです。
存在そのものが消えてしまうようなイメージですね。

一方、上記の書き方であれば、要素が画面外に移動するだけで表示はされています。
リアクティブに値を反映させておくこともできますね。

では、次はPHPの内容を見ていきましょう。

functions/mail.php

<?php
  
//jsで送られてきたデータを受け取り、変数に入れます。
//PHPでは変数の書き方は$と文字列となります。
$mailarea = htmlspecialchars($_POST['mailarea'], ENT_QUOTES);
$namearea = htmlspecialchars($_POST['namearea'], ENT_QUOTES);
$textboxarea = htmlspecialchars($_POST['textboxarea'], ENT_QUOTES);
  
//以下はメールを送るための1セットのソースコードだと思ってください。
//まずは文字コードを日本語,UTF-8に設定します。
header("Content-Type:text/html; charset=UTF-8");
mb_language("japanese");
mb_internal_encoding("utf-8");
  
//送信先のメールアドレスを変数に入れておきます。
//ただ、変数という箱に入れただけでこれで送れるとかではありません。
$mail="info@startout.work";
//タイトルを変数に入れておきます。
$sub1="[自動返信] STARTOUTへのお問合せが完了しました";
//$mailareaとは、ユーザーが入力したメールアドレスです。
//$mail_toという変数に入れて、送る時に使います。
$mail_to = $mailarea;
  
//メールの本文を書きます。
//改行しながら変数に一行ずつ書いていきましょう。
$messegeall .= "STARTOUTへのお問合せありがとうございます。\n";
$messegeall .= "今後とも、何卒、よろしくお願いいたします。\n";
$messegeall .= "\n";
$messegeall .= "─登録内容の確認─────────────────\n";
$messegeall .= "\n";
$messegeall .= "お名前:".$namearea."\n";
$messegeall .= "メールアドレス:".$mailarea."\n";
$messegeall .= "テキスト:\n";
$messegeall .= $textboxarea."\n";
$messegeall .= "\n";
$messegeall .= "─────────────────────────\n";
$messegeall .= "\n";
$messegeall .= "============================================\n";
$messegeall .= "このメールは自動送信です。\n";
$messegeall .= "お心当たりのない方は、お手数をおかけいたしますが、\n";
$messegeall .= "下記メールアドレスまでご連絡ください。\n";
$messegeall .= "============================================\n";
$messegeall .= "\n";
$messegeall .= "ログイン : https://startout.work/login.php\n";
$messegeall .= "\n";
$messegeall .= "━━━━━━━━━━━━━━━━━━━━━━━━━━\n";
$messegeall .= " STARTOUT\n";
$messegeall .= " 本 社:〒143-0021\n";
$messegeall .= "     東京都大田区北馬込2-41-8\n";
$messegeall .= " E-mail:info@startout.work\n";
$messegeall .= "━━━━━━━━━━━━━━━━━━━━━━━━━━\n";
$messegeall .= " 関連プロジェクト\n";
$messegeall .= " ◆グローバルな「デザイナー×エンジニア×起業家人材」を\n";
$messegeall .= "  育成する「IT留学シェアハウス」セブ島\n";
$messegeall .= " 《WORKROOM》https://workroom.biz/\n";
$messegeall .= "━━━━━━━━━━━━━━━━━━━━━━━━━━\n";
  
//ここでメールを送信します。
//下記のフォーマットの該当箇所にデータの入った変数をいれましょう。
//$success1=mb_send_mail(送り先メアド,タイトル,メッセージ内容,"From:".送り元メアド);
//しかし、これだけでは「自動返信メール」が届きません。
$success1=mb_send_mail($mail_to,$sub1,$messegeall,"From:".$mail);
//自動返信メールは送り先メアドと、送り元メアドを交換すると送れます。
$success2=mb_send_mail($mail,$sub1,$messegeall,"From:".$mail_to);
  
//最後はjsonという形で送信メッセージをjsに戻します。
header('Content-type: application/json');
echo json_encode( "送信が完了しました!" );
  
?>

基本、PHPでは、メールを送る処理しかしていません。
なので、例えばVue.jsでなくjQueryを使ったとしても、中身は同様です。

このファイルは1つのテンプレートみたいなものだと思ってください。
jsからポストする手段では、だいたい使いまわせます。

最近はこのようにフロントエンドとバックエンドの組み合わせが一般的です。
フロントエンドだけでなく、バックエンドも合わせてできる必要性が高まっています。
この機会にバックエンドも学んでみてはいかがでしょうか。

WEBサービスづくり学習「STARTOUT」はじめました!

自分の「WEBサービス」を作りながら「制作技術」を習得しよう!

STARTOUTとは、WEB制作×サービス作りのオンライン実践学習サービスです。ゼロからWEBサービスを作り、収益化しながら技術を習得してみましょう!

 詳細はこちら
  • このエントリーをはてなブックマークに追加

ウエヤマ ショウタ

WEB制作 ✕ 事業づくり学習サービス「STARTOUT」|事業づくり実践学習サービス「WAREHOUSE」|教えない学校、IT留学シェアハウス「WORKROOM」|以上3つ運営してます。近々、上記の成果を束ねて、クリエイターと起業家が生まれ、事業が生み出され続ける町を作る人。ベルリンのホルツマルクトはロールモデル。

ウエヤマ ショウタ

WEB制作 ✕ 事業づくり学習サービス「STARTOUT」|事業づくり実践学習サービス「WAREHOUSE」|教えない学校、IT留学シェアハウス「WORKROOM」|以上3つ運営してます。近々、上記の成果を束ねて、クリエイターと起業家が生まれ、事業が生み出され続ける町を作る人。ベルリンのホルツマルクトはロールモデル。

WEBサービスづくり学習「STARTOUT」はじめました!

自分の「WEBサービス」を作りながら「制作技術」を習得しよう!

STARTOUTとは、WEB制作×サービス作りのオンライン実践学習サービスです。ゼロからWEBサービスを作り、収益化しながら技術を習得してみましょう!

 詳しくはこちら