beta

Vue.js + Vuexでkeep-aliveなコンポーネントに戻った時にstateを更新する方法

お気に入りの管理とかで、一覧から詳細ページに移った際に、一覧ページをkeep-aliveしていると、詳細ページから一覧に戻った時に、stateが更新されなかったので、解決方法を探してみました。

公開日:2019年9月10日

想定ケース

  • List.vue (一覧ページ / keep-alive)
  • Detail.vue (詳細ページ)

一覧ページ、詳細ページ、どちらでもお気に入りの追加、削除ができるようにします。

普通のやり方だとkeep-alive側がstateを更新してくれない

普通に考えたら、mappGettersで、お気に入り一覧のデータを取り出して、連携させたアクションを実行すれば良いですよね。

import { mapGetters, mapActions } from "vuex"

export default {
  computed: {
    ...mapGetters([
      'starItems',
    ]),
  },
  methods: {
    ...mapActions([
      "storeStars"
    ]),
    setStar(){
      // お気に入りデータを更新する処理
    }
  }
}

こんな感じ。

実際に、これでもstate自体は更新されているのですが、keep-aliveしている一覧ページに戻ると、コンポーネントが再描画されないので、stateの更新が更新されません。(当たり前っちゃ当たり前)

watchを使ってルート変更時に強制的に再描画さればOK!

じゃあどうするのかということで、色々試した結果、唯一stateの更新を反映してくれるやり方がwatchを検知してコンポーネントを更新するやり方でした。

import { mapGetters, mapActions } from "vuex"

export default {
  computed: {
    ...mapGetters([
      'starItems',
    ]),
  },
  watch: {
    '$route' (to, from) {
      this.setStar()
    }
  },  
  methods: {
    ...mapActions([
      "storeStars"
    ]),
    setStar(){
      // お気に入りデータを更新する処理
    }
  }
}

これだと、keep-aliveしているキャッシュされたコンポーネントでも、ルート変更を検知して、setStarを実行してくれます。

ただし、一覧丸ごとリロードしてしまうと、せっかくのkeep-aliveが意味なくなってしまうので、お気に入りボタンなどだけコンポーネントを分けておくと良いです。

デメリットは、うまく処理しないと一覧の生成時に処理が重くなります。


Vue.js + Vuexでkeep-aliveなコンポーネントに戻った時にstateを更新する方法でした。

あまりスマートなやり方ではないかもしれませんが、とりあえずこれでも出来ますよというサンプルとかしてどうぞ。