Vuex is one state management that’s made to work with Vue apps.
To use it, we install it by running:
npm i vuex
Then we can register the Vuex
plugin and create a basic Vuex store with:
import Vue from "vue";
import App from "./App.vue";
import Vuex from "vuex";
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++;
}
}
});
Vue.config.productionTip = false;
new Vue({
store,
render: h => h(App)
}).$mount("#app");
The store is created with the Vuex.Store
constructor:"
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++;
}
}
});
The object we passed into the constructor has the state
property with the count
state inside it.
The initial value of count
is 0.
The mutations
property has methods that change the state.
We have the increment
method which takes the state
parameter.
It has the same content as the state
property above it.
So we can run state.count++
to increment the value of the count
state.
To make the store available to the rest of our app, we put store
into the object we passed into the Vue
constructor.
Then in a component, we can use the store as follows:
<template>
<div id="app">
<button @click="increment">Increment</button>
<p>{{count}}</p>
</div>
</template>
<script>
export default {
computed: {
count() {
return this.$store.state.count;
}
},
methods: {
increment() {
this.$store.commit("increment");
}
}
};
</script>
We have this.$store
, which is the Vuex store. We have this object since we registered the Vuex
plugin and put the store
into the object we passed into the Vue
constructor.
this.$store.state.count
has the count
state’s value.
And this.$store.commit
lets us commit values to the store.
The 'increment'
indicates that we call the increment
method in the mutations
property in the object we pass into the Vuex.Store
constructor.
We also have an Increment button to call increment
.
Now when we click the button, we’ll see the count
value displayed below the button go up.
The commit
method takes a 2nd argument, which is the payload.
So we can write:
import Vue from "vue";
import App from "./App.vue";
import Vuex from "vuex";
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment(state, payload) {
state.count += payload;
}
}
});
Vue.config.productionTip = false;
new Vue({
store,
render: h => h(App)
}).$mount("#app");
and write:
<template>
<div id="app">
<button @click="increment">Increment</button>
<p>{{count}}</p>
</div>
</template>
<script>
export default {
computed: {
count() {
return this.$store.state.count;
}
},
methods: {
increment() {
this.$store.commit("increment", 2);
}
}
};
</script>
to increment by 2 instead of 1 when we click.
We have:
this.$store.commit("increment", 2);
instead of:
this.$store.commit("increment");
and:
mutations: {
increment(state, payload) {
state.count += payload;
}
}
instead of:
mutations: {
increment(state,) {
state.count ++;
}
}
payload
is the 2 we passed in.
A basic Vuex store can let us store an app-wide state easily.
We just have to commit mutations to set the state and get the state from the store via the $this.store.state
property.
We can return the latest value in the computed property so we can use it.