1
votes

How can I detect changes of the getter value inside the template? I have the following component:

  computed: {
    ...mapGetters({
      processingStep: 'products/processingStep',
    }),

<div class="col" v-if="processingStep !=='last'">
...
...
</div>

So when I click the button in the Vuex state value for processingStep is getting changed during the time. The thing is that inside Vue dev tools I see updated getter value but my componnet template does not track it. How can this be fixed and how can above div be aware about processingStep value change?

2
Where in the devtools do you see this updated changes? Inside vuex tab or the component tab? I suspect you might not have the correct namespace/path to "processingStep" - Sølve Tornøe
inside vuex bindings - user12009061
How are you changing your vuex value? are you assigning it like this: state.step = 'last'? (using equals) - Sølve Tornøe
Nope committing mutation inside the action which is used inside button click. - user12009061
Can you please show how it might work with watch and getter inside the component? - user12009061

2 Answers

1
votes

You should be able to subscribe to your store's mutation. Subscribing is essentially like creating an event listener for any time a mutation is called on your store. For example, if your processingStep value is changed by a mutation called setProcessingStep:

export default {
  data() {
    return {
      processingStep: null
    }
  },
  mounted() {
    this.$store.subscribe((mutation, state) => {
      if (mutation.type === 'setProcessingStep') {
        this.processingStep = state.processingStep
      }
    })
  }
}
1
votes

This is a basic example on how this should work. I tried to mock your setup. Below is a working example of a getter being reactive to change the vue v-if in the DOM.

Maybe this example helps you spot an error you might have made in your code.

I will not add the example using a watcher, due to this being the correct way to use vuex with getters. Using a watcher would be avoiding the real problem and be considered bad practice.

I also suspect you might have broken the vue reactivity in your app. If you look at the vuex docs: Mutations Follow Vue's Reactivity Rules and Vue Change Detection Caveats

This essentially means that Vue cannot detect changes applied for objects and arrays done in a specific way.

For objects: Typically when you add foreign keys that was not there on initialization

For Arrays: When you directly set an item with the index or change the length

Vue.use(Vuex);
const store = new Vuex.Store({
  modules: {
    products: {
      strict: true,
      namespaced: true,
      state: {
        step: 'first'
      },
      getters: {
        processingStep(state) {
          return state.step;
        }
      },
      mutations: {
        CHANGE_STEP(state) {
          state.step = 'last'
        }
      }
    }
  }
});

const demo = new Vue({
  el: '#demo',
  store: store,
  computed: {
    ...Vuex.mapGetters({
      processingStep: 'products/processingStep'
    })
  },
  methods: {
    changeStep() {
      this.$store.commit('products/CHANGE_STEP')
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/2.3.1/vuex.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.js"></script>
<div id="demo">
  <p>processingStep: {{ processingStep }}</p>
  <button @click="changeStep">change Step</button>
  <div class="col" v-if="processingStep !=='last'">
    First step! :D
  </div>
  <p v-else-if="processingStep !== 'first'">
    This is the last..
  </p>
</div>