9
3

More than 1 year has passed since last update.

【vue】モーダルを開いた状態でブラウザバックした時に閉じる

Last updated at Posted at 2023-02-01

目的:モーダルを開いた状態でブラウザバックした際、前ページに遷移するのではなくモーダルを閉じたい。

バージョン:Vue 3
<script setup> 構文( https://v3.ja.vuejs.org/api/sfc-script-setup.html
モーダルには vue-final-modal (vfm) を使用します ( https://vue-final-modal.org/

セットアップ

インストール@3.4.4 を使用
npm install vue-final-modal@3
プラグインの読み込み
import vfmPlugin from "vue-final-modal";
const app = createApp(App);
app.use(vfmPlugin);
app.mount("#app");

実際の手順

まずはtemplate内にモーダルを開くボタンを設置。

template
<!-- モーダルを開くリンク -->
<a @click.prevent="openTestModal">クリック</a>

クリックすると モーダル表示フラグ showTestModal がtrueに(開いた状態に)

vue3
<script setup lang="ts">
    //モーダルの開閉フラグ 
    const showTestModal = ref(false);

    const openTestModal = () => {
      showTestModal.value = true
    }
    const closeTestModal = () => {
      showTestModal.value = false
    }
</script>

template内にモーダル部分を追加
閉じる を押すと closeTestModal が発火し showTestModal が falseになる

template
<!-- vue-final-modal -->
<vue-final-modal
    v-model="showTestModal"
    name="testModal"
    overlay-class="test-modal-overlay"
    :classes="['test-modal-container']"
    :content-class="['test-modal-class1', 'test-modal-class2']"
    transition="vfm"
    overlay-transition="vfm-o"
    :click-to-close="false"
    >
  <div class="test-modal-header">
    <p class="test-modal-heading">テストモーダル</p>
  </div>
  <div class="test-modal-content">
    <div style="text-align: center;">
      コンテンツ<br>
      <a @click="closeTestModal" class="c-button01 -outline">閉じる</a>
    </div>
  </div>
</vue-final-modal>
名前 説明
click-to-close オーバーレイクリックで発火しないように
classes モーダル領域(コンテナ)のカスタムクラス名を指定
content-class モーダル本体のカスタムクラス名を指定
transition モーダル本体に適用されるトランジション(デフォルト値:vfm)
overlay-transition オーバーレイに適用されるトランジション(↑本体とtransitionに差をつけたいので別で指定)
その他細かいプロパティの設定は公式の `propaties` (https://vue-final-modal.org/guide/properties/ )に

これで通常のvfm開閉ができるようになった。

vue3
<script setup lang="ts">
    //モーダルの監視
    watch(showTestModal, () => {
      if(showTestModal.value == true) {
        window.history.pushState(null, '', null);
        window.addEventListener("popstate", closeTestModal);
      } else {
        window.removeEventListener("popstate", closeTestModal);
      }
    })
</script>

showTestModal のフラグを watch で監視し、ブラウザバックxを検知したらイベント発火させる。

戻るボタンを無効化
window.history.pushState(null, '', null);

popstateイベントで閉じるイベント closeTestModal を呼び出す

戻るボタンを無効化
window.addEventListener("popstate", closeTestModal);

これでブラバ無効+モーダルを閉じることができるようになりました。

全文
<script setup lang="ts">
import { ref, watch } from "vue";

//モーダルの監視
watch(showTestModal, () => {
  if(showTestModal.value == true) {
    window.history.pushState(null, '', null);
    window.addEventListener("popstate", closeTestModal);
  } else {
    window.removeEventListener("popstate", closeTestModal);
  }
})

</script>
<template>
    <!-- モーダルを開くリンク -->
    <a @click.prevent="openTestModal">クリック</a>
    
    <vue-final-modal
        v-model="showTestModal"
        name="testModal"
        overlay-class="test-modal-overlay"
        :classes="['test-modal-container']"
        :content-class="['test-modal-class1', 'test-modal-class2']"
        transition="vfm"
        overlay-transition="vfm-o"
        :click-to-close="false"
        >
      <div class="test-modal-header">
        <p class="test-modal-heading">テストモーダル</p>
      </div>
      <div class="test-modal-content">
        <div style="text-align: center;">
          コンテンツ<br>
          <a @click="closeTestModal" class="c-button01 -outline">閉じる</a>
        </div>
      </div>
    </vue-final-modal>
</template>

9
3
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
9
3