Help us understand the problem. What is going on with this article?

Vue.js + axios使ってフォーム送信後に登録完了メッセージを出して3秒後に消すやつやってみた

More than 3 years have passed since last update.

■前提

Laravelベースのアプリでプロフィール登録のようなフォーム送信を行う機能を実装する際に、
Vue.js + axiosを使って、フォーム送信後に「登録完了!」みたいなメッセージが出て数秒後に消える機能を入れてみました。
ベースとなるテンプレートにはLaravelのbladeテンプレートを使用しています。

■処理の流れ

①ProfNameコンポーネント内に定義した入力フォームにデータを入力し、登録ボタンクリック
②クリックイベントをコンポーネント内で補足してリクエストデータを生成し親コンポーネントに送る
③親コンポーネントでイベントを補足したら非同期でDBに登録するメソッドを実行
④非同期処理実行後メッセージを表示する処理を実行
⑤setTimeoutでメッセージ表示の3秒後にメッセージを非表示にする処理を実行
※わざわざリクエストデータを親コンポーネントに送るのは非同期で登録する処理を他の項目でも使うため共通化したかったからです。

■コード

bladeテンプレート

<!-- profile.blade.php -->
<!-- メッセージを表示するmsgコンポーネント -->
<msg></msg>
<!-- 名前を登録するフォームのprof-nameコンポーネント -->
<!-- LaravelからUserのデータを受け取る 子コンポーネントからnamesentというイベントが送られてきたらeditValueメソッド(後ほど記載)を実行する-->
<prof-name v-bind:user="{{ $user }}" v-on:namesent="editValue"></prof-name>

ProfNameコンポーネント

<!-- /resources/assets/js/components/ProfName.vue -->
<template>
    <div>
        <label><span>ニックネーム</span></label>
        <div>
            <input name="name" type="text"v-model="name" placeholder="ニックネーム" required>
            <!-- buttonをクリックするとsendNameメソッドが実行される -->
            <button v-on:click="sendName">+</button>
        </div>
    </div>    
</template>
<script>
    export default {
        props:["user"],//profile.blade.phpからuserを受け取る
        data: function(){
            return{
                name:this.user.name,
                request:{
                    name:''
                }
            }
        },
        methods: {
            //リクエストに必要なidとrequestを親コンポーネントに送る
            sendName(){
                if(this.name){
                    this.request.name = this.name;
                    //namesentというイベントを送信
                    this.$emit("namesent",{
                        id:this.user.id,
                        request:this.request
                    });
                }
            }
        }
    }
</script>

Vueインスタンスの生成

//resources/assets/js/app.js

//・・Vueの読み込み等(割愛)

//コンポーネントの読み込み
//プロフィール入力フォーム
Vue.component('prof-name',require('./components/ProfName.vue'));
//登録後に出すメッセージ(色んな場所で使えるようにコンポーネント化)
Vue.component('msg',require('./components/common/Msg.vue'));

//Vueインスタンス生成
const app = new Vue({
    el: '#app',
    methods: {
        //コンポーネントから受け取ったデータを非同期でDBに保存する
        editValue(req){
            axios.patch('/users/' + req.id, req.request).then(res => {
                if(res.data.result === '成功'){
                    //msgコンポーネントをゆっくり表示
                    $(".msg_cover").addClass('msg_appear');
                    //3秒後にゆっくり非表示 setTimeoutを使えば簡単だった
                    setTimeout(function() {
                        $('.msg_cover').removeClass('msg_appear');
                    }, 3000);
                }
            });
        }
    },
});

msg_appearというクラスをつけたり外したりすることで、メッセージを表示させたり非表示にしたり出来ます。(msg_appearの詳細は下記)

Msgコンポーネント

<!-- /resources/assets/js/components/ProfName.vue -->
<template>
    <div class="msg_cover msg_hide">
        <p>登録完了!</p>
    </div>
</template>
<style type="text/css">
    /*基本スタイル*/
    .msg_cover {
        text-align: center;
        width: 100%;
        padding: 10px 0;
        height: 60px;
        line-height: 40px;
        font-size: 20px;
        background: pink;
        color: white;
        margin-left: -6%;
        z-index: 1000;
    }
    /*画面の60px上に置いて見えないようにしておく(デフォルト)*/
    .msg_hide {
        position: fixed;
        top: -60px;
        /*transitionで変化させる属性や変化速度、変化の仕方を記載(消す時)*/
        transition-property:top;
        transition-duration:.6s;
        transition-timing-function:ease-in-out;
    }
    /*画面上部に表示させる*/
    .msg_appear {
        top:0;
        /*transitionで変化させる属性や変化速度、変化の仕方を記載(表示させる時)*/
        transition-property:top;
        transition-duration:.6s;
        transition-timing-function:ease-in-out;
    }   
</style>

Vue.jsを使うとメッセージのコンポーネントを切り出せて、コンポーネント内に全てのスタイルをかけちゃうので便利でした。
子から親にデータを送るときに$emitを使ってイベントとして送る必要があるっぽいので少し面倒に感じますが、慣れたらどーってことないです。

Yorinton
NetFlix、Hulu、U-next、T-verを経てAmazonプライムに流れ着く。3度の飯より好きなものは特に無いけど、3度の飯時には必ずと言っていいほどアニメを嗜む。PHP、JS、TS、Vue.js、Laravel、少しだけGo. 開発責任者.
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした