Vuex Getters
Vuex getters behave a lot like Mongoose getters: they're special properties that are computed from other properties when you access them.
For example, suppose your store contains a user's firstName
and lastName
. You can write a getter that returns
the user's fullName
.
const Vuex = require('vuex');
const store = new Vuex.Store({
state: {
firstName: 'Bill',
lastName: 'Gates'
},
getters: {
fullName: state => `${state.firstName} ${state.lastName}`
}
});
store.getters.fullName; // 'Bill Gates'
Change Tracking
Vuex getters react to changes in the store's state just like computed properties. So if you update one of the state properties the getter relies on, the getter value updates too:
const store = new Vuex.Store({
state: {
firstName: 'Bill',
lastName: 'Gates'
},
getters: {
fullName: state => `${state.firstName} ${state.lastName}`
},
mutations: {
changeFirstName(state, val) {
state.firstName = val;
}
}
});
// When you commit a change, the next time you access the getter you get
// an updated value!
store.commit('changeFirstName', 'William');
store.getters.fullName; // 'William Gates'
mapGetters()
What makes getters so interesting is that you can use them in your component's
computed properties, so your UI updates whenever the state changes.
For example, below is a component that displays the computed fullName
and updates automatically whenever
the fullName
changes:
const store = new Vuex.Store({
state: {
firstName: 'Bill',
lastName: 'Gates'
},
getters: {
fullName: state => `${state.firstName} ${state.lastName}`
},
mutations: {
changeFirstName(state, val) {
state.firstName = val;
}
}
});
const app = new Vue({
store,
computed: {
fullName: function() {
return this.$store.getters.fullName;
}
},
methods: {
toggleName: function() {
const newName = this.fullName === 'William Gates' ? 'Bill' : 'William';
this.$store.commit('changeFirstName', newName);
}
},
template: `
<div>
<h1>{{fullName}}</h1>
<button v-on:click="toggleName">
Toggle
</button>
</div>
`
});
This is easy to write by hand for one computed property, but can get unwieldy if you need many computed properties.
That's why Vuex has a neat mapGetters()
helper that takes a list of property names and returns a list of computed
property functions.
const app = new Vue({
store,
// Equivalent to the previous example
computed: Vuex.mapGetters(['fullName']),
methods: {
toggleName: function() {
const newName = this.fullName === 'William Gates' ? 'Bill' : 'William';
this.$store.commit('changeFirstName', newName);
}
},
template: `
<div>
<h1>{{fullName}}</h1>
<button v-on:click="toggleName">
Toggle
</button>
</div>
`
});