当ブログ人気記事!
転職体験談
Laravelで学ぶWebアプリ開発
誰でも作れるチャットアプリ
未経験への勧め

【Laravel初心者向け講座】通報機能を実装してみる(フロント編:vueでモーダル画面作成)

プログラミング

モーダル画面をサクッと作りたい!
通報機能実装してみたい!

こういった方に対して書きました!


この記事を書いている私(@Shoot58153748)は、
2020年2月現在メガベンチャーの社内スタートアップの部署でエンジニア(1年目)をしており、

プログラミング未経験からメガベンチャーへの転職を成功させた経験・ノウハウ
Webエンジニアになってから学んだこと

をブログにまとめています。


前回、前々回はいいね機能(画面API)を実装しましたが、

今回から2記事(フロント側実装、API実装)にわたって、通報機能の実装をしていきます!

特に、今回は
モーダル画面
についてピックアップします。

Vueでの実装の方法などぜひ参考にしてください!


今回のポイント

  • モーダル画面のVueでの実装方法
  • Vueの変数で画面、ボタンの制御



今までのLaravelでのWebアプリ開発記事もまとめていますので、
こちらも参考にしてください!

また、ブログでは最低限必要な(更新した)部分のみ掲載するので、
全体のソースコードをみたい場合は以下にあげてあります。
Github: https://github.com/Shuto-san/laravel-vue-docker

スポンサーリンク

モーダル画面とは

モーダル(=modal)はモード(=mode)の形容詞で、「モード(様式)の」といった意味で使われます。

特にWebの世界においては、モーダルはモーダルウィンドウ(=modal window)のことをさします。

モーダルウィンドウとは、「あなたがこのウィンドウを閉じるまでなにもさせません」というウィンドウです。
つまり表示された操作を完了するか、キャンセルをしなければ、ウィンドウの外をクリックしても戻れません。

このため、モーダルウィンドウはユーザーに重要な操作や確認を促したりするときに使われます

近年は操作感が悪くなるという理由から、モーダルウィンドウを避けるデザイナーもいるみたいですが、

ユーザーにどうしても確認や警告したい際には必要になるテクニックです。
Webサイトに奥深さを与えてくれることでしょう。


通報前の確認メッセージを表示するために、
通報ボタンを押したらモーダル画面を表示するよう実装していきます!

画面イメージ

通報機能実装例(フロント側)

今回の制作物(実装内容)は以下になります。

  • 画面
  • SCSS
  • Js

画面

ファイル名:resources/views/index.blade.php

            <div class="contents">
                <div class="tweet-timeline">
                    <div class="tweet-card" v-for="tweet in tweets" :key="tweet.id" v-cloak>
                        <div class="tweet-contents">
                            <div class="tweet-contents-tweet">
                                <div>@{{ tweet.tweet }}</div>
                            </div>
                            <div class="tweet-contents-footer">
                                    <i v-if="tweet.is_liked" class="fas fa-heart" @click="pushLike(tweet)"></i>
                                    <i v-else class="far fa-heart" @click="pushLike(tweet)"></i>

                                    ///////////////通報ボタン///////////////////
                                    <i v-if="tweet.is_reported" class="fas fa-flag" @click="openModal(tweet)"></i>
                                    <i v-else class="far fa-flag" @click="openModal(tweet)"></i>
                                    ////////////////////////////////////////

                            </div>
                        </div>

                        ///////////////モーダル画面///////////////////
                        <section v-if="tweet.isDisplayed" class="modal-area">
                          <div class="modal-background"></div>
                          <div class="modal-wrapper">
                            <div class="modal-contents">
                              <h1 v-if="tweet.is_reported">通報を取り消しますか?</h1>
                              <h1 v-else>通報しますか?</h1>
                              <p>※意味不明なツイート、不快なツイート、誹謗中傷を含むツイートは通報できます</p>
                              <button v-if="tweet.is_reported" class="btn" @click="pushReport(tweet)">通報取消</button>
                              <button v-else class="btn" @click="pushReport(tweet)">通報する</button>
                            </div>
                            <div class="modal-close" @click="closeModal(tweet)">
                              ×
                            </div>
                          </div>
                        </section>
                        ////////////////////////////////////////

                    </div>
                </div>
                <infinite-loading @infinite="fetchTweets"></infinite-loading>
            </div>

通報ボタンとしてfontawesomeの通報(flag)アイコンを使用

通報していないツイートに関しては、<i class="far fa-flag">で白旗アイコン

既に通報したツイートに関しては、<i class="fas fa-flag">で黒旗アイコンが表示されます。

通報アイコンをクリックすると、
モーダル画面を開くメソッドopenModalが実行され、

tweet.isDisplayedの値でモーダル画面(<section>)部分の表示を制御


モーダル画面中の通報ボタンをクリックすると、
通報情報をサーバー側に送るpushReportメソッドが実行されます。


sassファイルでモーダル画面のデザインを記述していきます。

SASS

ファイル名:resources/sass/_modal.scss

/* モーダルCSS */
.modal {
    &-area {
        position: fixed;
        z-index: 10; /*サイトによってここの数値は調整 */
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
    }

    &-background {
        width: 100%;
        height: 100%;
        background-color: rgba(30,30,30,0.9);
    }

    &-wrapper {
        position: absolute;
        top: 50%;
        left: 50%;
        transform:translate(-50%,-50%);
        width: 70%;
        max-width: 500px;
        padding: 10px 30px;
        background-color: #fff;
    }

    &-close {
        position: absolute;
        top: 0.5rem;
        right: 1rem;
        cursor: pointer;
    }
}

modal-area:モーダルのエリアを定義
modal-background:モーダルの画面が黒くなる背景色を定義
modal-wrapper:モーダル画面を定義
modal-close:モーダル画面の閉じるボタンを定義

ファイル名:resources/sass/tweet.scss

// modal
@import 'modal';

先ほど作成したファイルをインポートしてあげます。

JS

ファイル名:resources/js/tweet.js

new Vue({
    el: '#tweet',
    data: {

...

    },
    methods: {
        fetchTweets($state) {

...

            .then(response => {
                if (response.data.tweets.length) {
                    this.page++;
                    response.data.tweets.forEach (value => {
                        value.isDisplayed = false; // 追加
                        this.tweets.push(value);
                    });
                    $state.loaded();
                } else {
                    $state.complete();
                }
            })
            .catch(error => {
                console.log(error);
            })

        },

/////////////追加///////////////////
        pushReport(tweet) {
            this.postReport(tweet.id, !tweet.is_reported);
            tweet.is_reported = !tweet.is_reported;
            tweet.isDisplayed = false;
        },

        postReport(tweetId, reportPushed) {
            axios.post(window.location.origin + `/tweet/report`, {
                tweetId: tweetId,
                reportPushed: reportPushed
            })
            .then(response => {
            })
            .catch(error => {
            });
        },

        openModal(tweet) {
            tweet.isDisplayed = true;
        },

        closeModal(tweet) {
            tweet.isDisplayed = false;
        }
    },
///////////////////////////////////

...

});

サーバーからツイート一覧をフェッチした際に、
tweetオブジェクトにモーダル画面のDisplayを制御する変数isDisplayedを追加。

ボタンの制御は、tweetオブジェクトのプロパティis_reported(サーバー側で定義)で行います。

メソッドは以下の通り
pushReport:モーダル画面中の通報ボタンを押したら実行される。サーバーにポストして、モーダル画面とボタンの変数を設定する

postReport:サーバーに通報情報をポストする

openModal:通報アイコンをクリックすると、モーダル画面を表示する

closeModal:モーダル画面の閉じるボタンをクリックすると、モーダル画面を閉じる


最後にnpm run devでSASSとJSをビルドするのを忘れずに!!

まとめ:モーダル画面はvueの変数で制御すると便利

以上、通報機能のフロント側の実装でした!

今回のポイント

  • モーダル画面のVueでの実装方法
  • Vueの変数で画面、ボタンの制御

モーダル画面は、Vueで実装するととてもシンプルです。

モーダル画面&デザインCSSを作成

画面やボタンを制御するための変数を用意し、v-ifで制御

という流れで実装できます。


モーダル画面を実装できるようになれば、
Webサイトに奥深さを加えてくれることでしょう。

次回は通報機能のAPIを実装します!




それではまた!

プログラミング
スポンサーリンク
シェアする
SHOOTをフォローする
WebエンジニアSHOOTのブログ

コメント

タイトルとURLをコピーしました