Search code examples
vue.jsvuex

How to call mutation on state change


I have a web app that has multiple components in App.Vue but will show one at a time and I'm keeping track with a variable 'Step' in Store. So something like this:

<div class="hero-body main-content-container">
  <Welcome id="intro" v-if="steps == 1"></Welcome>
  <template v-cloak>
    <Keywords id="keywords" v-if="steps == 2"></Keywords>
    <Ads v-if="steps == 3"></Ads>
  </template>
</div>

I'm not sure what best practice is so that I can watch the state of 'Step' and when it reach a certain step I want to call a certain mutation before any of the code that runs within the actual component. I was thinking of using a watch property in the App.vue file but it seems like using a watcher like this isn't a great idea, from the context I've read online.


Solution

  • I would store your Step in the store and only change it through actions. Then you have complete control over what happens and when.

    For example

    const store = new Vuex.Store({
      state: {
        step: 1,
        // etc
      },
      mutations: {
        incrementStep (state) {
          if (state.step < MAX_STEPS) { // just a precaution
            state.step += 1
          }
        },
        // etc
      },
      actions: {
        nextStep ({ commit, state }) {
          commit('incrementStep')
          if (state.step === A_CERTAIN_STEP) {
            commit('certainMutation')
          }
        }
      }
    })
    

    Then your components can dispatch the "nextStep" action without having to do anything else.