VueX Modules
VueX Modules: is important for large scale project as it make developer more easier to separate store state as module for example moduleOne and moduleTwo.
Each module has its own state, getters, actions, mutations and namespace. However, namespace is optional. Nevertheless, it is best practice to have it to prevent some conflicts among modules state, actions, getters, mutations.
Example: I have two modules with namespace inside.
moduleOne
moduleTwo
Those two modules are simple as they are fairly the same.
Module Registration
It is quite simple for registering, however, i have new state as global.
Dispatch actions handler function from vue component
Right now, you are on vue component so how you dispatch from methods properties to actions properties inside VueX store. Take a look below
Now you see that moduleOne and moduleTwo are the namespace for moduleOne and moduleTwo respectively inside VueX store.
What we do in vue component is to specify namespaces registered in methods properties:
Note: root state or getters can also be used inside local state for each module. see example :
rootState/rootGetters now can be used to inside local state and Total product will be 5 as it should have been 4.
Final result :
You can investigate by clicking on any buttons to see how mutations can be done.
Each module has its own state, getters, actions, mutations and namespace. However, namespace is optional. Nevertheless, it is best practice to have it to prevent some conflicts among modules state, actions, getters, mutations.
Example: I have two modules with namespace inside.
moduleOne
const moduleOne = {
namespaced: true,
state: {
products:[
{id:1,name:'pizza', price:10},
{id:2, name:'fan', price: 20},
{id:3, name:'headset', price:30 },
{id:4,name: 'phone', price: 1004}
]
},
mutations: {
deductPrice( state ) {
return state.products.map(item => item.price -= 1)
},
multPrice( state, payload ) {
return state.products.map(item => item.price *= payload.price)
}
},
getters:{
getBigPrice (state ) {
return state.products.filter(item => item.price >= 10)
},
getCountItem ( state, getters, rootState ) {
return getters.getBigPrice.length + rootState.products.length
}
},
actions:{
deductPrice({commit}) {
return new Promise((resolve, reject) => {
setTimeout(() => {
commit('deductPrice')
resolve()
},1000)
})
},
multPrice( { commit, dispatch }, payload ) {
return dispatch('deductPrice').then(() => {
commit('multPrice', payload)
})
}
}
}
moduleTwo
const moduleTwo = {
namespaced: true,
state: {
buildings:[
{id:1,name:'room', done:true},
{id:2, name:'house', done: false},
{id:3, name:'toilet', done:true },
{id:4,name: 'kitchen', done: true }
]
},
mutations: {
doneBuilding( state, done ) {
return state.buildings.forEach(item => {
if( !item.done ) {
item.done = true
}
});
},
doneBuildingCount( state ) {
return state.buildings.length
}
},
getters:{
buildingCount(state){
return state.buildings.length
},
getBuildings( state ) {
return state.buildings.filter(item => item.done)
}
},
actions:{
doneBuilding({commit}, done) {
return new Promise((resolve, reject) => {
setTimeout(() => {
commit('doneBuilding', done)
resolve()
},1000)
})
},
doneBuildingCount( { commit, dispatch } ) {
return dispatch('doneBuilding').then(() => {
commit('doneBuildingCount')
})
}
}
}
Module Registration
It is quite simple for registering, however, i have new state as global.
const store = new Vuex.Store({
state:{
products:[{id: 5, name:'bin', price: 300}]
},
modules:{
moduleOne: moduleOne,
moduleTwo: moduleTwo
}
})
Dispatch actions handler function from vue component
Right now, you are on vue component so how you dispatch from methods properties to actions properties inside VueX store. Take a look below
const Counter = {
template: `<div> Total product: {{ itemCount }}
<li v-for="product in products"> Id:{{ product.id }},
name:{{ product.name }}, Price:{{ product.price }} </li><br/>
<button @click="deductPrice">Deduct</button>
<button @click="multPrice">Multiply</button><br/>
Total building: {{ buildingCount }}
<li v-for="building in buildings"> Id:{{ building.id }},
name:{{ building.name }}, Done:{{ building.done }} </li><br/>
<button @click="doneBuilding(true)">Only Done</button>
</div>`,
computed:{
...mapGetters(
{ products: 'moduleOne/getBigPrice',
itemCount: 'moduleOne/getCountItem'}
),
...mapGetters({
buildingCount:'moduleTwo/buildingCount',
buildings: 'moduleTwo/getBuildings'
})
},
methods:{
deductPrice(){
this.$store.dispatch({type:'moduleOne/deductPrice'})
},
multPrice() {
this.$store.dispatch({ type:'moduleOne/multPrice', price:2 })
},
doneBuilding(done){
this.$store.dispatch({type:'moduleTwo/doneBuilding', done: done})
}
}
}
Now you see that moduleOne and moduleTwo are the namespace for moduleOne and moduleTwo respectively inside VueX store.
What we do in vue component is to specify namespaces registered in methods properties:
this.$store.dispatch({ type:'moduleOne/multPrice', price:2 })
this.$store.dispatch({type:'moduleTwo/doneBuilding', done: done})
and computed properties:
{ products: 'moduleOne/getBigPrice',
itemCount: 'moduleOne/getCountItem'}
{
buildingCount:'moduleTwo/buildingCount',
buildings: 'moduleTwo/getBuildings'
}
Note: root state or getters can also be used inside local state for each module. see example :
getCountItem ( state, getters, rootState ) {
return getters.getBigPrice.length + rootState.products.length
}
Final result :
You can investigate by clicking on any buttons to see how mutations can be done.

Comments
Post a Comment