Tech

vuexで1つのwatchハンドラで複数のstate変更を監視する方法 [$store.watch()] Vue2

Vuexのstore(ストア)を使うと、各コンポーネント間で個別にデータのやり取りすることなく、データを一元的に管理できます。Vueでは欠かせない機能といえるでしょう。

state(変数、コンポーネントでのプロパティにあたる)の状態変化を監視して、任意のactionなどを実行する、といった使い方もします。

今回はstoreの状態監視をするとき、複数のstateを同じwatchハンドラで監視する方法を紹介します。主な対象はVue2です。

実行環境

vue@2.6.12

 

何がしたいか

以下のような state があるとします。

state: {
    userDataAlpha: false,
    userDataBeta: true,
  }

watchハンドラでそれぞれのstateの状態変化を監視し、同じ関数を実行したいとき、個別のwatchに登録しようとすると以下のように書けます。

mounted() {
    this.$store.watch(
      (state, getters) => getters.getUserDataAlpha,
      (newVal, oldVal) => {
        console.log(`Updated ${oldVal} to ${newVal}`);
      },
    )
    this.$store.watch(
      (state, getters) => getters.getUserDataBeta,
      (newVal, oldVal) => {
        console.log(`Updated ${oldVal} to ${newVal}`);
      },
    )
  },

このときuserDataAlphaを変化させると、コンソールには以下のように出力されます。

Updated true to false
Updated false to true

しかし上記のようにすると、同じ内容を書くことになり冗長です。
できればやりたくありません。

そこで以下のようなテクニックで書き直します。

 

Vuexのstateを一つのwatchハンドラで監視する

方法1. 配列にまとめて deep:true を指定

stateを以下のように連想配列の形に変更します。

state: {
    userData: {
      userDataAlpha: true,
      userDataBeta: true,
    }
  },

こうすれば userDataの中身がひとつでも変化すればwatchがキャッチしてくれます。

watch()にdeep:trueパラメータを渡します。

mounted() {
    this.$store.watch(
      (state, getters) => getters.getUserData,
      (newVal) => {
        console.log(`${newVal.userDataAlpha}, ${newVal.userDataBeta}`);
      },
      { deep: true }
    )
  },

userDataAlphaを変化させると、コンソールには以下のように出力されるはずです。

false, true
true, true

 

方法2. トリックを使う

コンポーネントのcomputed プロパティにて、あらかじめstateをひとつに結合しておき、それを監視する方法です。

computed: {
    ...mapState(["userDataAlpha", "userDataBeta"]),
    userDatasCombined() {
      return `${this.userDataAlpha},${this.userDataBeta}`;
    },
  },

userDatasCombinedを用意しておき、それをコンポーネントのwatch()に登録します。

watch: {
    userDatasCombined(newVal, oldVal) {
      console.log(`Updated (${oldVal}) to (${newVal})`);
    }
  }

userDataAlphaを変化させると、コンソールには以下のように出力されるはずです。

Updated (true,true) to (false,true)
Updated (false,true) to (true,true)
  • この記事を書いた人

nextpenguin

システム開発・プログラミングのしごとやっています。甘味とコーヒーは生命線。日常での学びを記事にしています。

-Tech
-, ,

© 2021 スターレイヴ