Store
Vuex
For vuex we are using, at least, two plugins.
vuex-module-configuration-composerto automagicly import our modulesvuex-persistedstateto persist in local storage certain modules (or none of them)
index.js default file (ready to go in most cases)
import Vue from 'vue'
import Vuex from 'vuex'
import { generateVuexStoreModuleConfiguration } from 'vuex-module-configuration-composer'
import createPersistedState from 'vuex-persistedstate'
Vue.use(Vuex)
const context = require.context('./modules', true, /index\.js$/)
const storeConfiguration = Object.assign(
{
plugins: [
createPersistedState({
paths: ['auth'],
}),
],
},
generateVuexStoreModuleConfiguration(context)
)
export default new Vuex.Store(storeConfiguration)
File structure
src
└── store
├── index.js
└── modules
└── ...
We are not using root state, getters, actions and mutations. We will use a global module for global stuff that does not fit with any other module.
Rules
State
Avoid setting computed state
This might be obvious but try not to create repetitive data that could be easily computed with a getter.
// bad
export default {
users: [],
adminUsers: [],
employeeUsers: []
}
Getters
Never create a computed in your component that only implies store data
If every element that computed needs already lives in the store you should do a getter.
// bad
computed: {
isAdmin() {
return this.$store.auth.state.user.isSuperAdmin || this.$store.auth.state.user.isSuperAdmin
}
}
// good (in getters)
isAdmin: state => state.user.isSuperAdmin || state.user.isAdmin
Actions
Always destructure store context object
This practice would help to linter unused vars and see at a first sight which store functions are we using inside the action
// bad
myAction(store, payload) {
store.commit(MY_MUTATION, payload)
}
// good
myAction({ commit }, payload) {
commit(MY_MUTATION, payload)
}
Always import mutation constant
Avoid hardcoding mutation strings.
// bad
myAction({ commit }, payload) {
commit('My Mutation', payload)
}
// good
import { MY_MUTATION } from './mutation-types'
myAction({ commit }, payload) {
commit(MY_MUTATION, payload)
}
Mutations
Mutations types exported as const
Mutation types should be exported as const in order to get IDE autocompletion
export const MY_MUTATION = 'My Mutation'
Constants must be uppercased and value human readable
In order to quickly identify a mutation, the constant should be uppercased. In the other hand, its value should be human readable for debugging (You can use emojis if you want)
export const SING_IN = '🔒 Sign In'
Mutation names
We would try to use a convention naming for typical CRUD mutations
- SET_ENTITY: Setting or Updating a pice of state
- RESET_ENTITY: Setting a pice of state to its initial value
- ADD_ENTITY: Adding an item to a collection
- UPDATE_ENTITY: Updating an item in a collection
- DELETE_ENTITY: Deleting an item from a collection
Mutating Arrays
In most cases we will use a single strategy mutating state in arrays.
[ADD_POST]: (state, post) => {
state.posts = [...state.posts, post]
}
[UPDATE_POST]: (state, post) => {
const index = state.posts.findIndex(p => p.id === post.id)
state.posts.splice (index, 1, item)
}
[DELETE_POST]: (state, post) => {
state.posts = state.posts.filter(p => p.id !== post.id)
}