ブログの投稿ログ

2021年
9月
8月
7月
6月

Vuexを使ったモーダル実装

本日はVuexで状態管理しつつモーダルの実装をしたいと思います。


今日のコード

codesandbox


HelloWorld.vue

<template>
  <div>
    // モーダルのクリックイベントを作成
    <button @click="openModal('modal')">モーダル表示</button>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  methods: {
    // storeへ引数で定義したモーダル名を渡す
    openModal(target) {
      this.$store.dispatch("openModal", target);
    },
  },
};
</script>

モーダルのクリックイベントの引数にモーダル名を入れ、それをvuexの管理場所であるstoreへ送っています。


store/index.js


.....
.....

  state: {
    modal: {
      //  表示/非表示を管理
      isShow: false,
      // 表示するモーダル名を管理
      target: ""
    }
  },

  actions: {
    // クリックイベントで取得した値をミューテーションへ送る

    openModal({ commit }, target) {
      commit("openModal", { target: target });
    },
    closeModal({ commit }) {
      commit("closeModal");
    }
  },

  mutations: {
    openModal(state, { target }) {
      // モーダルを表示する処理をstateへ
      state.modal.isShow = true;
      // モーダル名をstateへ
      state.modal.target = target;
    },
    closeModal(state) {
      // モーダルを非表示する処理をstateへ
      state.modal.isShow = false;
      // 非表示にするモーダル名をstateへ
      state.modal.target = "";
    }
  }
});

export default store;


App.vue

<template>
  <div id="app">
    <HelloWorld />
    // store内で定義した表示/非表示を定義
    <div v-if="$store.state.modal.isShow" class="modal-base">
      // どのモーダルコンポーネントを表示するか
      <component :is="$store.state.modal.target" />
    </div>
  </div>
</template>

<script>
import HelloWorld from "./components/HelloWorld";

export default {
  name: "App",
  components: {
    HelloWorld,
    // モーダルコンポーネントをインポート
    Modal: () => import("@/components/modal"),
  },
};
</script>

<template>
  <div class="modal">
    <div class="content">
      <h3>モーダルですよ</h3>
      // クリックイベントを定義
      <button  @click="closeModal">
        閉じる
      </button>
    </div>
  </div>
</template>

<script>
export default {
  name: "Modal",
  methods: {
    // storeへ送信
    closeModal() {
      this.$store.dispatch("closeModal");
    },
  },
};
</script>

今回は以上です!