hkのweblog

ひよっこエンジニアがにわとりになるまでの軌跡

Vue.jsでsetTimeoutする時の注意点

月2更新目標のこのブログ、だいぶ更新をサボってしまいました…
書けなかった理由は色々あるんですが、ライトなネタで再開します。

というわけで今日はVue.jsネタ。
プライベートで作っているサービスですが、

  1. 入力フォームで確認ボタンを押す
  2. 確認モーダルが表示される
  3. モーダル上の投稿ボタンを押す
  4. 成功にせよ失敗にせよモーダル内にメッセージが表示される
  5. 3秒後にモーダルを閉じる
    ということをしようと思いました。 この3~5のところをsetTimeoutを使って実装しようとしたのがこんな感じ

Modal.vue

<template>
    <transition name="modal">
        <div class="overlay" @click="$emit('close')">
            <div class="panel" @click.stop>
                <b>投稿してよろしいですか?</b>
                <p>お名前:{{form.name}}</p>
                <p>メールアドレス:{{form.mailAddress}}</p>
                <button v-on:click="postArticle">投稿する</button>
                <button @click="$emit('close')">閉じる</button>
                <p>{{message}}</p>
            </div>
        </div>
    </transition>
</template>

<script>
export default {
    data() {
        return {
            message: ''
        }
    },
    // 親コンポーネントから渡してるform
    props: ['form'],
    methods: {
        postArticle:function() {
            let self = this.form;
            let article = {
                name: self.name,
                mailAddress: self.mailAddress
            };
            this.$http.post('/api/article/', article).then(response => {
                this.message = "登録が完了しました";
                setTimeout(this.closeModal(), 3000);
            }).catch(error => {
                //サーバーからjsonでエラーメッセージを投げる
                this.message = error.response.data.error;
                setTimeout(this.closeModal(), 3000);
            });
        },
        closeModal:function() {
            //親コンポーネント側でモーダルを消す処理
            this.$parent.showModal = false;
        }
    }
}
</script>

これがだめでした。投稿するボタンを押すと3秒待たずすぐにcloseModal()が実行されてしまうのです。
で、解決策はこれだけ

//これを
setTimeout(this.closeModal(), 3000);
//こうする
setTimeout(this.closeModal, 3000);

はい。それだけでした。
ほんとドキュメント読めよって感じですね… developer.mozilla.org setTimeoutって有名だけど普段フロントエンド触らないマン的にはあんまり書く機会ないよね、という言い訳…
あれ?これVue関係なくね…?と今更思いました。

以上です。