ブログの投稿ログ

2021年
9月
8月
7月
6月

mutationsやactionsに第三引数を渡したい

大きさの違うモーダルを一つのモダールコンポーネントで扱いたい時にVueXを使ったのですが、複数の情報を引数にいれる場合実装に詰まったのでその解決策を書いていきたいと思います。

でも

// HelloWorld.vue

<template>
  <div>
    // 大きいモーダルを表示するボタン
    <button @click="openModalBig('modal')">大きいモーダル表示</button>
    <br />
    // 小さいモーダルを表示するボタン
    <button @click="openModalSmall('modal')">小さいモーダル表示</button>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  methods: {
    openModalBig(target) {
      // 第二引数にオブジェクトにして値を入れ込む
      this.$store.dispatch("openModal", { target: target, size: "big" });
    },
    openModalSmall(target) {
      // 第二引数にオブジェクトにして値を入れ込む
      this.$store.dispatch("openModal", { target: target, size: "small" });
    },
  },
};
</script>

VueXのdispatchメソッドには第二引数までしか受付られないとのことでオブジェクトで値を渡してあげます。

// store/index.js

import Vue from "vue";
import Vuex from "vuex";
import createPersistedState from "vuex-persistedstate";

Vue.use(Vuex);

const store = new Vuex.Store({
  modules: {},
  plugins: [createPersistedState()],

  state: {
    modal: {
      isShow: false,
      target: "",
      size: ""
    }
  },

  actions: {
    // オブジェクトにして受け取る
    openModal({ commit }, { target, size }) {
      // 変数に値を代入する
      const modalData = {
        target: target,
        size: size
      };
      // 変数をmutationsへコミットする
      commit("openModal", modalData);
    },
    closeModal({ commit }) {
      commit("closeModal");
    }
  },

  mutations: {
    // 引数を受け取ってstateを値に入れていく
    openModal(state, { target, size }) {
      state.modal.isShow = true;
      state.modal.target = target;
      state.modal.size = size;
    },
    closeModal(state) {
      state.modal.isShow = false;
      state.modal.target = "";
    }
  }
});

export default store;

// modal.vue

<template>
  <div class="modal">
    // 状態に応じたクラスを定義
    <div :class="classes">
      <h3>モーダルですよ</h3>
      <button @click="closeModal">閉じる</button>
    </div>
  </div>
</template>

<script>
export default {
  name: "Modal",
  methods: {
    closeModal() {
      this.$store.dispatch("closeModal");
    },
  },
  computed: {
    classes() {
      // 先ほどstoreで入れたsizeを呼び出し
      const classes = ["content", `--${this.$store.state.modal.size}`];
      return classes;
    },
  },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.modal {
  position: absolute;
  top: 0;
  background: #000;
  width: 100%;
  height: 100vh;
  background: rgba(0, 0, 0, 0.7);
}
// 大きいモーダルのクラス
.--big {
  width: 400px;
}
// 小さいモーダルのクラス
.--small {
  width: 200px;
}
h3 {
  color: 000;
}
.content {
  background: #fff;
  margin: 60px auto 0;
  padding: 60px;
}
</style>