0
1

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 1 year has passed since last update.

axiosでページ遷移してフラッシュメッセージを出す!

Last updated at Posted at 2022-04-16

何をするか?

WEBサービス内でコンテンツを削除したりする際にモーダル画面を出す時は
Vue.jsでやったりする方が楽だったりします。

その際にaxiosを使用して削除実行後に特定のページ、または同一ページに遷移した後に
フラッシュメッセージを出したいとします。いや、出したい。

*削除ボタン押してモーダルが出るこんなイメージ
ダウンロード.gif

削除用ルーティング

web.php
  Route::post('/delete/{id}','DeleteController@idea_delete')->name('delete');

下記の様に削除ボタンがあったとしましょう。
今回は簡単な例なのでController内の記述は省きます
propsで削除する対象のidとweb.phpに記載してるルーティングを記載
ちなみに文字列をpropsで渡す場合は「:」付けるとエラーになります。

item_detail.blade.php
        <div id="delete" class="p-ideaform__btngroup">
            <delete-component :id={{ $item->id }} path={{"/delete/"}}></delete-component>
        </div>

propsの値を渡すvueファイルが下

DeleteButton.vue
<template>
  <div>
    <div>
     <!-- クリックしたらモーダル開きます -->
      <a @click="openModal" class="c-card__btn"
        >削除</a
      >
    </div>
    <!-- 削除押した際のモーダル -->
    <transition name="modal">
      <div class="p-modal__body" v-if="modalFlg">
        <h3>削除しますか?</h3>
        <img :src="'/images/hatena.png'" alt="" class="p-modal__image" />
        <div class="p-modal__btn">
          <span class="c-btn u-green p-modal__btn--no" @click="closeModal">NO</span>
          <button class="c-btn u-blue p-modal__btn--yes" @click="deleteItem(id)">YES</button>
        </div>
      </div>
    </transition>
  </div>
</template>

<script>
export default {
  //idにはbladeテンプレートから渡されたid。pathには「/delete/」が入ってきますね。
 props: ["id","path"],
  data: function () {
    return {
     //最初はモーダルは閉じておくので初期値はfalse
      modalFlg: false,
    };
  },
  methods: {
//削除ボタンクリックしたらモーダル開く為のメソッドを定義
    openModal() {
      this.modalFlg = true;
    },
//NOボタンクリックしたらモーダル閉じる為のメソッドを定義
    closeModal() {
      this.modalFlg = false;
    },
//モーダルの「YES」を押したら削除
  deleteItem(id) {
 //pathの中身は「/delete/id(propsで受け取ったidの値)」になります。
        const path = this.path + id;
//一つ下で定義してあるaxiosメソッドにpathを渡して実行
        this.axios(path);
 
    },
    axios(path) {
      axios
        .post(path)
        .then((res) => {
              //「https://hoge.com/mypage」というURLなら
              //location.protocolは「https:」を取得
              //location.hostnameは「hoge.com」を取得
              //location.replace()は指定したパスに遷移させるJSのメソッド。なので
              //下記は「https://hoge.com/mypage」へ遷移させる。
              const link =location.protocol + "//" + location.hostname +  "/mypage"
             // window.sessionStorage.setItem([プロパティ名],[値])でセッションに保存できる。
              window.sessionStorage.setItem(['flash_message'],['アイデアを削除しました']);
              location.replace(link);
          }
        })
        .catch(function (err) {
          console.log(err);
        });
    },
  
  },

};
</script>

それでapp.blade.phpなどに実際のフラッシュメッセージのマークアップ

app.blade.php
@include('layouts.head')

<body>
    <div id="app" class="l-main js-main">
      <!-- この中にフラッシュメッセージ -->
        <div class="js-delete-message c-flash">
            <span class="js-delete-text c-flash_text"></span>
        </div>
        @yield('content')
       
    </div>
    @include('layouts.footer')
</body>

</html>


後はjQueryで操作できる

flash.js

  const msg = window.sessionStorage.getItem(['flash_message']);
  //もしセッションにメッセージがあればスライドダウンさせる
  if(msg !== null){
    $('.js-delete-text').html(msg);
    $('.js-delete-message').slideDown();
  //ほんで3秒後にしまってセッション削除
  //セッションの削除はwindow.sessionStorage.removeItem([プロパティ名])
    setTimeout(()=>{
      $('.js-delete-message').slideUp();
      window.sessionStorage.removeItem(['flash_message']);
    },3000)
  }
  

おまけのCSS

style.scss
//フラッシュメッセージ
.c-flash{
  background: rgb(157, 241, 223);
  opacity: .8;
  width: 100%;
  height: auto;
  min-height: 50px;
  position: absolute;
  text-align: center;
  font-weight: bold;
  padding: 16px 10px;
  z-index: 300;
  display: none;
  overflow-wrap: break-word;
}
//気になる解除を押した時に表示されるモーダル

.p-modal{

  &__body{
    background: #ddd;
    padding: 18px 10px;
    position: fixed;
    z-index: 10;
    top: 10%;
    left: 50%;
    width: 40%;
    text-align: center;
    transform: translateX(-50%);
    @include mq(ls){
      width: 70%;
    }
   
    h3{
      text-align: center;
    }
    @include mq(sp){
      width: 90%;
    }
    
  }
  
  &__image{
    width: 80%;
    margin: auto;
    display: block;
  }
  &__btn{
    display: flex;
    width: 100%;
    justify-content: space-around;
    margin-top: 16px;

    &--no{
      @include mq(ls){
        padding: 24px 36px;
      }
    }
    &--yes{
      @include mq(ls){
        padding: 24px 36px;
      }
    }
  }
}



Vue.jsのtransitionアニメーション

vue.css


//Vue.jsのtransition
.modal-enter-active {
  //要素が挿入される『前』に追加される。アニメーション終わったら削除
  transition: all 0.5s;
  opacity: 0;
  transform: translate(-50%, 20px);
}
.modal-enter-to {
  //要素が挿入された『後』に追加される。アニメーション終わったら削除
  transition: all 0.5s;
  opacity: 1;
  transform: translate(-50%, 0);
}

.modal-leave-active {
  //要素が削除される『前』に追加。アニメーション終わったら削除
  transition: 0.6s;
  opacity: 1;
  transform: translate(-50%, 0);
}

.modal-leave-to {
  //要素が削除された『後』に追加。アニメーション終わったら削除
  transition: 0.6s;
  opacity: 0;
  transform: translate(-50%, 20px);
}

今回は以上です。
ちょっと長いですが、処理は単純。
特に削除機能は結構使用するのでvueコンポーネントで作成しておくと
使い勝手良いですね。
スタイルを変えたい時等はpropsでクラス名渡してあげたりすればOK

0
1
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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?