Doubt in computed method Vue using Vuex

1

I have the following code below using Vue.js and Vuex . This code increments and decrements value as a counter. I would like to know the count method within computed in the Vue instance. I know it returns the count status of state . But why does the method name have to be the name of the variable? If I change the method name the code does not work.

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    incrementa: state => state.count++,
    decrementa: state => state.count--
  }
})

new Vue({
  el: '#app',
  computed: {
    count() {                   // Dúvida -> ao que se refere count
      return store.state.count
    }
  },
  methods: {
    incrementa() {
      store.commit('incrementa')
    },
    decrementa() {
      store.commit('decrementa')
    }
  }
})
span{padding: 0 15px;}
<script src="https://unpkg.com/[email protected]/dist/vuex.js"></script><scriptsrc="https://unpkg.com/[email protected]/dist/vue.js"></script>

<div id="app">
  <p>
    <button @click="incrementa">+</button>
    <span>{{ count }}</span>
    <button @click="decrementa">-</button>
  </p>
</div>
    
asked by anonymous 12.09.2018 / 15:51

3 answers

1

The computed property of the Vue object is where your Computed Properties is declared.

You can think of Computed Properties as properties where only getters (and optionally, setters) are defined for something. There is no value registered in the property, but a getter function that may or may not fetch the desired value elsewhere. One of the advantages of using Computed Properties in Vue.JS is that Vue caches the getter result, and invalidates the cache if the getter dependencies are changed.

Basic example using computed property to calculate the full name:

var app = new Vue({
    el: '#app',
    data: {
      nome: '',
      sobrenome: ''
    },
    computed: {
      nome_completo: function () {
        // concatena e elimina espaços em excesso
        return '${this.nome } ${this.sobrenome}'.replace(/\s+/g, ' ')
      }
    }
});
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script><divid="app">
  <input v-model="nome">
  <input v-model="sobrenome">
  <div>{{ nome_completo }}</div>
</div>

Now, answering the reason why your code gives error to change the name of the computed property:

The state count is one thing, computed property count is another.

The state count is only referenced within the function contador() in the line

return store.state.count

The computed property count is being referenced in the template, in line

<span>{{ count }}</span>

To access computed property you must access it through the Vue object. Example:

this.count  // Acessa a computed property

To access state count you must access it through Vuex. In your example:

store.state.count

I just modified the name of computed property in the Vue object and in the template to show how it works with different names.

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    incrementa: state => state.count++,
    decrementa: state => state.count--
  }
})

new Vue({
  el: '#app',
  computed: {
    contador() {  // agora é contador
      return store.state.count
    }
  },
  methods: {
    incrementa() {
      store.commit('incrementa')
    },
    decrementa() {
      store.commit('decrementa')
    }
  }
})
span{padding: 0 15px;}
<script src="https://unpkg.com/[email protected]"></script><scriptsrc="https://cdn.jsdelivr.net/npm/vue"></script>

<div id="app">
  <p>
    <button @click="incrementa">+</button>
    <span>{{ contador }}</span> <!-- printa a computed property -->
    <button @click="decrementa">-</button>
  </p>
</div>
    
12.09.2018 / 20:13
1

In this case, the name of the method within computed does not have to be the same name as the variable, but the name of the attribute that is inside the state must be the same name of the attribute within its store . See this in the example below:

const store = new Vuex.Store({
      state: {
        count: 0
      },
      mutations: {
        incrementa: state => state.count++,
        decrementa: state => state.count--
      }
    })

    new Vue({
      el: '#app',
      computed: {        
        count() {                   // Dúvida -> ao que se refere count
          return store.state.count
        },
        teste() {
          return store.state.count
        }        
      },
      methods: {
        incrementa() {
          store.commit('incrementa')
        },
        decrementa() {
          store.commit('decrementa')
        }
      }
    })
span{padding: 0 15px;}
<script src="https://unpkg.com/[email protected]/dist/vuex.js"></script><scriptsrc="https://unpkg.com/[email protected]/dist/vue.js"></script>

<div id="app">
  <p>
    <button @click="incrementa">+</button>
    <span>{{ count }}</span>
    <span>{{ teste }}</span>    
    <button @click="decrementa">-</button>
  </p>
</div>

However, it's usually more commonly used in real-world applications, mapState , where it gets less repetitive use of store and more clear what you're actually mapping to your stores , especially when there are more than one.

Another point to note is that in an actual application you perform an injection of the store within the Vue instance itself usually speaking, so it is used with this.$store and not store directly.

    
12.09.2018 / 18:07
1

You can think of these methods within computed as variables that self-update, ie in the template you will have access to a "variable" with the name of that method.

In the template you have <span>{{ count }}</span> and this count is the return of that count(){ within computed .

So you see each computed property / method as variables that are always updated. This update is due to an internal mechanism of the Vue (reactivity) and that records the dependencies that this method has. And when one of these dependencies is updated the method is run again and the value of count updated.

    
12.09.2018 / 19:47