1.什么是Vuex?
Vuex是一個(gè)專(zhuān)門(mén)為Vue.js應(yīng)用程序開(kāi)發(fā)的狀態(tài)管理模式, 它采用集中式存儲(chǔ)管理所有組件的公共狀態(tài), 并以相應(yīng)的規(guī)則保證狀態(tài)以一種可預(yù)測(cè)的方式發(fā)生變化.

上面圖片中綠色虛線部分就代表的是Vuex的核心。
state:
其中state相當(dāng)于vue實(shí)例中的data,用來(lái)保存所有組件的公共數(shù)據(jù)。
mutations:
state只能通過(guò)mutations進(jìn)行修改,不可以直接修改state數(shù)據(jù)。
actions:
actions類(lèi)似于mutations,不過(guò)actions提交的是 mutations,而不是直接變更狀態(tài)。actions中可以包含異步操作, mutations中絕對(duì)不允許出現(xiàn)異步。
2.為什么要使用Vuex?
多個(gè)組件之間互相通信,會(huì)非常的繁瑣,所以在多個(gè)組件共享數(shù)據(jù)的時(shí)候需要用到Vuex。
安裝:
使用 npm:
import Vuex from 'vuex'
Vue.use( Vuex );
創(chuàng)建一個(gè)項(xiàng)目:
export default new Vuex.Store({
state: {
},
mutations: {
},
getters: {
},
actions: {
}
})
new Vue({
el: '#app',
store,
render: h => h(App)
})
3.Vuex的核心概念
1.state:
其中state相當(dāng)于vue實(shí)例中的data,用來(lái)保存所有組件的公共數(shù)據(jù)。
2.getters:
我將getters屬性理解為所有組件的computed屬性, 也就是計(jì)算屬性. vuex的官方文檔也是說(shuō)到可以將getter理解為store的計(jì)算屬性, getters的返回值會(huì)根據(jù)它的依賴(lài)被緩存起來(lái),且只有當(dāng)它的依賴(lài)值發(fā)生了改變才會(huì)被重新計(jì)算。
mapGetters 輔助函數(shù):
mapGetters 輔助函數(shù)僅僅是將 store 中的 getter 映射到局部計(jì)算屬性:
import { mapGetters } from 'vuex'
export default {
// ...
computed: {
// 使用對(duì)象展開(kāi)運(yùn)算符將 getter 混入 computed 對(duì)象中
...mapGetters([
'doneTodosCount',// 把 `this.doneTodosCount` 映射為 `this.$store.getters.doneTodosCount`
'anotherGetter',
// ...
])
}
}
這樣就可以在組件中 使用 this.doneTodosCount 直接調(diào)用store的getters中的doneTodosCount方法了
3.mutations:
我將mutaions理解為store中的methods, mutations對(duì)象中保存著更改數(shù)據(jù)的回調(diào)函數(shù),該函數(shù)名官方規(guī)定叫type, 第一個(gè)參數(shù)是state, 第二參數(shù)是payload, 也就是自定義的參數(shù).
調(diào)用mutations必須用store.commit()提交
store.commit('方法', 參數(shù))
// 支持載荷和對(duì)象方式進(jìn)行分發(fā)
// 以載荷形式分發(fā)
store.commit('incrementAsync', {
amount: 10
})
// 以對(duì)象形式分發(fā)
store.commit({
type: 'incrementAsync',
amount: 10
})
Mutation 必須是同步函數(shù)
mapMutations 輔助函數(shù):
mapMutations 輔助函數(shù)僅僅是將 store 中的 mutations 映射到局部計(jì)算屬性:
import { mapMutations } from 'vuex'
export default {
// ...
methods: {
...mapMutations([
'increment', // 將 `this.increment()` 映射為 `this.$store.commit('increment')`
// `mapMutations` 也支持載荷:
'incrementBy' // 將 `this.incrementBy(amount)` 映射為 `this.$store.commit('incrementBy', amount)`
]),
...mapMutations({
add: 'increment' // 將 `this.add()` 映射為 `this.$store.commit('increment')`
})
}
}
4.actions:
actions 類(lèi)似于 mutations,不同在于:
- actions提交的是mutations而不是直接變更狀態(tài)
- actions中可以包含異步操作, mutations中絕對(duì)不允許出現(xiàn)異步
- actions中的回調(diào)函數(shù)的第一個(gè)參數(shù)是context, 是一個(gè)與store實(shí)例具有相同屬性和方法的對(duì)象
一個(gè)簡(jiǎn)單的actions:
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment')
}
}
})
實(shí)踐中,我們會(huì)經(jīng)常用到 ES2015 的 參數(shù)解構(gòu) 來(lái)簡(jiǎn)化代碼(特別是我們需要調(diào)用 commit 很多次的時(shí)候):
actions: {
increment ({ commit }) {
commit('increment')
}
}
調(diào)用actions必須用store.dispatch()觸發(fā)(分發(fā))
store.dispatch('方法', 參數(shù))
// 支持載荷和對(duì)象方式進(jìn)行分發(fā)
// 以載荷形式分發(fā)
store.dispatch('incrementAsync', {
amount: 10
})
// 以對(duì)象形式分發(fā)
store.dispatch({
type: 'incrementAsync',
amount: 10
})
mapActions 輔助函數(shù):
mapActions 輔助函數(shù)僅僅是將 store 中的 actions 映射到局部計(jì)算屬性:
import { mapActions } from 'vuex'
export default {
// ...
methods: {
...mapActions([
'increment', // 將 `this.increment()` 映射為 `this.$store.dispatch('increment')`
// `mapActions` 也支持載荷:
'incrementBy' // 將 `this.incrementBy(amount)` 映射為 `this.$store.dispatch('incrementBy', amount)`
]),
...mapActions({
add: 'increment' // 將 `this.add()` 映射為 `this.$store.dispatch('increment')`
})
}
}
5.Modules:
由于使用單一狀態(tài)樹(shù),應(yīng)用的所有狀態(tài)會(huì)集中到一個(gè)比較大的對(duì)象。當(dāng)應(yīng)用變得非常復(fù)雜時(shí),store 對(duì)象就有可能變得相當(dāng)臃腫。為了解決以上問(wèn)題,Vuex 允許我們將 store 分割成模塊(module)。每個(gè)模塊擁有自己的 state、mutation、action、getter、甚至是嵌套子模塊——從上至下進(jìn)行同樣方式的分割
const moduleA = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: { ... },
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> moduleA 的狀態(tài)
store.state.b // -> moduleB 的狀態(tài)