Doubt in Vue computed method using Vuex

Asked

Viewed 341 times

1

I have the following code below using Vue.js and Vuex. This code increments and decreases value as a counter. I would like to know what the method refers to count inside computed in Vue instance. I know it returns the state of the variable Count of state. But why does the method name have to be the variable name? 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>
<script src="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>

3 answers

1

In this case, the name of the method within the computed does not need to be the same name as the variable, but the name of the attribute that is within the state must be the same name as 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>
<script src="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 is commonly used in real-world applications mapState, where the use of store and clearer what you are really mapping to your stores, especially when there is more than one.

Another point that should be noted, is that in a real application you perform an injection of the store within the very instance of Vue usually speaking, so it is used with this.$store and not store directly.

  • All right, you came up with another method (Testing) inside computed that returns the store with the state of the variable Count and this method does the same as the method Count, right. Only doubt persists, if you change the name of the method count() error, this you would like to know pq? You said in your reply "In this case, the method name inside the computed does not need to be the same variable name", tries to rename Count() to see if there is no error.

  • Dude if you change the computed Count() you have to change the HTML to the name you changed, did you change it? computed is like a data() variable, so it has to change in HTML as well, the name of HTML and computed must be exactly the same.

  • Exact man, it was this even though I wasn’t getting it. I switched on computed but not HTML. Thanks plea help!

1

You can think of these methods within computed as variables that update themselves, that is in the template you will have access to a "variable" named after that method.

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

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

1


The estate computed of the object Vue is where its Computed Properties.

You can think of Computed Properties as properties where only getters (and optionally, setters) are defined for something. There is no registered value in the property, but a getter function that may or may not search for 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>

<div id="app">
  <input v-model="nome">
  <input v-model="sobrenome">
  <div>{{ nome_completo }}</div>
</div>

Now, answering why your code gives error when changing the name of computed Property:

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

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

return store.state.count

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

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

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

this.count  // Acessa a computed property

To access the state count you need to access it through Vuex. In your example:

store.state.count

Below I changed only the name of computed property in the Vue object and 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>
<script src="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>

  • Okay man, got it now. I didn’t know that the {{ Count }} that referenced the method count(). That’s why I made a mistake, because I only changed my name on computed and not interpolation. Now it’s clear. Thank you!

  • This... the variables you try to print in the template ({{ variable }}) are always searched in the Vue object, because the template is part of the component as well.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.