I'm studying Vue (2.x) + Vuex for some time now and one pattern that I've always seen around is the use of Mutation Types.
To me it is just unnecessary code to add complexity to a project with more files, maybe I didn't have enough experience with it to understand the real usage, therefore this question.
According to the Mutation Types docs it states that it is entirely optional and you should use if you like it also states that "This allows the code to take advantage of tooling like linters, and putting all constants in a single file allows your collaborators to get an at-a-glance view of what mutations are possible in the entire application" and it stop there.
And Also:
Whether to use constants is largely a preference - it can be helpful in large projects with many developers, but it's totally optional if you don't like them
What I would like to understand is what exactly are the advantages here both for tooling and in the so called large projects. Some examples of it would be really nice.
Even the sample code in the docs is silly enough to discourage it:
//mutation-types.js
export const SOME_MUTATION = 'SOME_MUTATION';
// store.js
import Vuex from 'vuex'
import { SOME_MUTATION } from './mutation-types'
const store = new Vuex.Store({
state: { ... },
mutations: {
// we can use the ES2015 computed property name feature
// to use a constant as the function name
[SOME_MUTATION] (state) {
// mutate state
}
}
})
Instead of just:
// store.js
import Vuex from 'vuex'
const store = new Vuex.Store({
state: { ... },
mutations: {
//To me this is already clear enough to understand the purpose
//of the mutation and to see AT-A-GLANCE what all mutations in the
//Application are
someMutation (state) {
// mutate state
}
}
})
Specially because modern IDEs (Eclipse, Npp does that) already have the grouping features which means that you will se it all at-a-glance like:
...
mutations: {
+ someMutation1
+ someMutation2
+ someMutation3
+ someMutation4
+ someMutation5
+ someMutation6
+ someMutation7
}
...
Without seen a practical usage of such a thing I think this is like the 5 Monkeys Experiment
Mutations are a responsible for single state changes. We'll show you how and create the mutation needed to set the products in our store, and we'll stress the importance of understanding the true difference between actions and mutations. We'll also implement what we've learned in our shopping cart app.
In Vuex, actions are functions that call mutations. Actions exist because mutations must be synchronous, whereas actions can be asynchronous. You can define actions by passing a POJO as the actions property to the Vuex store constructor as shown below. To "call" an action, you should use the Store#dispatch() function.
Mapping in Vuex enables you to bind any of the state's properties, like getters, mutations, actions, or state, to a computed property in a component and use data directly from the state. Although we can get the job done with this. $store.state.user.data.name , we can use a map helper to simplify it to this.
Let's take a look at why Vuex is is still necessary, even in Vue 3. First, Vuex offers advanced debugging capabilities that Vue 3 features does not. This is a huge bonus for developers, since no one wants to spend all that time debugging! Secondly, Vuex has plugins that extend its capabilities.
Say that you have this example:
// store.js
import Vuex from 'vuex'
const store = new Vuex.Store({
state: { ... },
mutations: {
setRelationshipWithRolePlayers (state) {
// mutate state
}
}
})
and then in another component I do:
this.$store.commit('setRelationshipsWithReolePlayers');
Importing constant saves you from spending time debugging issues caused by small typos like the one above, which sadly occurs more often than what we would like to.
Also when you have a lot of mutations and actions (it's nice to use mutations types also for actions) it's not easy to remember how they are called, so importing them from a mutation-types
file makes it super easy to auto import constants with auto completion.
Also having all the mutations and actions in the same file makes it easy to check whether a mutation/action name is already used in another part of the project without having to make global searches (keep in mind that as the project grows you probably want to modularise you store or have more than one store).
It probably won't determine the success or failure of your project, but it can be of great help, and save you a good amount of time in medium-big projects
I use Mutation Types to skip typos while using mapMutations
or to use Symbol
as method names
// mutation-types.js
export const SOME_MUTATION = 'SOME_MUTATION'
export const SOME_MUTATION_SYMBOL = Symbol('SOME_MUTATION')
// store.js
import Vuex from 'vuex'
import { SOME_MUTATION, SOME_MUTATION_SYMBOL } from './mutation-types'
const store = new Vuex.Store({
state: { ... },
mutations: {
// we can use the ES2015 computed property name feature
// to use a constant as the function name
[SOME_MUTATION] (state) {
// mutate state
},
[SOME_MUTATION_SYMBOL] (state) {
// mutate state
}
}
})
import { mapMutations } from 'vuex'
import { SOME_MUTATION, SOME_MUTATION_SYMBOL } from './mutation-types'
export default {
// ...
methods: {
...mapMutations([
// 'SOME_MUTATION'
SOME_MUTATION // no typos and you get IDE intellisence
]),
...mapMutations({
localName: SOME_MUTATION_SYMBOL // map to localName
})
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With