Reputation: 481
In the following code, components (app.vue) c2
property does not get updated when increment
updates stores counter this.$store.state.counter++;
I know I can solve this by using c2
as computed
property but I would like to know why Vuex or vue does not initiate reactivity since the counter's value was updated by increment method.
Store.js
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export const store = new Vuex.Store({
state: {
counter: 0
},
mutation: {
increment() {
return this.$state.counter++;
}
}
});
App.vue
<template>
<div id="app">
<button @click="increment">Increment</button>
{{ c2 }}
</div>
</template>
<script>
export default {
data() {
return {
c2: this.$store.state.counter
};
},
methods: {
increment() {
this.$store.state.counter++;
}
}
};
</script>
Thanks
Upvotes: 0
Views: 1447
Reputation: 1615
Vuex uses something called "actions" and they look just like mutations, but instead of mutating the state, they commit mutations. You can't modify your Vuex store state like this:
methods: {
increment() {
this.$store.state.counter++
}
}
Instead, you should create a actions object inside your store with an action:
actions: {
increment (context) {
context.commit('increment')
}
}
Now, that code says this: "whenever you dispatch me (action), run the code inside the mutation called increment" which means: "commit the mutation called increment".
Another important thing is your component method called "increment". You should modify it to look like this:
methods: {
increment() {
this.$store.dispatch('increment')
}
}
Now, whenever you call this method you will dispatch an action that will commit a mutation.
Finally, in order to get your state inside your component (the good way at least) would be using the mapState
function that Vuex provides.
First, import this inside your component script tag:
import { mapState } from 'vuex'
And create a computed property like this:
computed: mapState([
'counter'
])
This will give you access to the counter
property that was define inside your store state. In that case, you can delete the return statement in your data()
function and change your html in order to display the counter
property:
<template>
<div id="app">
<button @click="increment">Increment</button>
{{ counter }}
</div>
</template>
And that would be it!
Upvotes: 1