Search code examples
vue.jsvuejs2vue-componentvuex

Why counter is not being displayed in vue js by using getters?


As you can see in code below i have store.js where I am doubling my value by 2 using getters but while accessing it in result this.$store.state.doubelCounter; is showing as undefined.

I have this store.js for vuex

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export const store = new Vuex.Store({
    state: {
        counter: 0
    },
    getters: {
        doubleCounter: state => {
            return state.counter * 2;
        } 
    }
})

This one is counter.vue:

<template>
    <div>
        <button class="btn btn-primary" @click="increment">Increment</button>
        <button class="btn btn-primary" @click="decrement">Decrement</button>
    </div>
</template>

<script>
    export default {
        methods: {
            increment() {
                this.$store.state.counter++;
            },
            decrement() {
                this.$store.state.counter--;
            }
        }
    }
</script>

This is result.vue:

<template>
  <p>Counter is: {{ counter }}</p>
</template>

<script>
export default {
  computed: {
    counter() {
      return this.$store.state.doubelCounter;
    },
  },
};
</script>

Solution

  • First, you can't mutate store's state directly. The only way to do that is to commit a mutation:

    export const store = new Vuex.Store({
      state: {
        counter: 0
      },
      getters: {
        doubleCounter: state => state.counter * 2
      },
      mutations: {
        incrementCounter(state) {
          state.counter++;
        },
        decrementCounter(state) {
          state.counter--;
        }
      },
    })
    

    Then, in counter.vue:

    <template>
        <div>
            <button class="btn btn-primary" @click="incrementCounter">Increment</button>
            <button class="btn btn-primary" @click="decrementCounter">Decrement</button>
        </div>
    </template>
    
    <script>
      import { mapMutations } from 'vuex';
    
      export default {
        methods: {
          ...mapMutations(['incrementCounter', 'decrementCounter'])
        }
      }
    </script>
    

    Second, to access store's getter, you should use $store.getters instead of $store.state in result.vue:

    <template>
      <p>Counter is: {{ counter }}</p>
    </template>
    
    <script>
    export default {
      computed: {
        counter() {
          return this.$store.getters.doubleCounter; // "doubel" typo fixed
        },
      },
    };
    </script>