最近比較閒,抽時間過了一遍vuex的文檔。同時寫了官網上購物車的那個小demo。下面來總結一下一些vuex的一些知識點vue
官方文檔上寫:vuex是一個專爲vue.js應用程序開發的狀態管理模式。這個狀態自管理應用包括如下幾個部分:vuex
vuex應用的核心就是store(倉庫)。"store"基本上就是一個容器,它包含着你的應用中大部分的狀態(state)。數組
在vue組件中獲取狀態異步
// 建立一個 Counter 組件 const Counter = { template: `<div>{{ count }}</div>`, computed: { count () { return store.state.count } } }
使用mapState輔助函數
在一個組件須要獲取多個狀態的時候,將這些狀態都聲明爲計算屬性會有些複雜。爲了解決這個問題,可使用mapState輔助函數模塊化
// 在單獨構建的版本中輔助函數爲 Vuex.mapState import { mapState } from 'vuex' export default { computed: mapState({ count: state => state.count, // 傳入字符串'count'等同於'state => state.count' countAlias: 'count', // 使用模塊而且對應模塊名稱爲cart時,獲取cart裏面對應的count屬性 count: state => state.cart.count }) }
當計算屬性的名稱與state子節點名稱相同時,能夠給mapState傳入一個字符串數組函數
computed: mapState([ 'count' ])
對象展開運算符...mapStatethis
computed: { localComputed() { ...mapState({ }) } }
從store中的state派生出一些狀態。能夠理解爲store的計算屬性。當getter所依賴的值發生改變時,getter的值會隨之改變。spa
import { mapGetters } from 'vuex' export default { // ... computed: { // 使用對象展開運算符將 getter 混入 computed 對象中 ...mapGetters([ 'doneTodosCount', 'anotherGetter', // ... ]) } }
若是你想將一個 getter 屬性另取一個名字,使用對象形式:code
mapGetters({ // 把 `this.doneCount` 映射爲 `this.$store.getters.doneTodosCount` doneCount: 'doneTodosCount' })
模塊化狀態下,getter取值對象
// 模塊爲cart computed: { ...mapGetters('cart', { doneCount: 'doneTodosCount' }) }
更改vuex的store中的狀態的惟一辦法是提交mutation
注意:
mutation必須是同步函數,異步須要放在aciton中
const store = new Vuex.store({ state: { count:1 }, mutations: { increment (state) { state.count++ } } })
store.commit('increment')
提交載荷(Payload)
你能夠向store.commit傳入額外的參數,即mutaition的荷載(payload)
mutations: { increment(state, n) { state.count += n } } store.commit('increment', 10)
在組件中提交mutation
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')` }) } }
Action相似於mutation。不一樣在於:
const store = new Vuex.Store({ state: { count: 0 }, mutations: { increment (state) { state.count++ } }, actions: { increment (context) { context.commit('increment') } // 或者也能夠用es2015的解構賦值寫成下面這種形式 increment({ commit }) { } } })
分發Action
Action經過store.dispatch方法觸發
store.dispatch('increment')
在組件中分發Action
import { mapActions } from 'vuex' export default { // ... methods: { ...mapActions([ 'increment', //將this.increment()映射爲this.$store.dispatch('increment') ]) ...mapActions([ add: 'increment' // 將 `this.add()` 映射爲 `this.$store.dispatch('increment')` ]) } }
Vuex容許咱們將store分割成模塊。
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 的狀態 store.state.b // -> moduleB 的狀態
默認狀況下,模塊內部的action、mutation和getter是註冊在全局命名空間的。若是你但願你的模塊具備更高的封裝度和複用度,你能夠經過添加namespaced:true的方式使其成爲帶命名空間的模塊。在模塊被註冊後,它全部getter、action及mutation都會自動根據模塊註冊的路徑調整命名。
const store = new Vuex.Store({ modules: { account: { namespaced: true, state: {}, getters: { isAdimin() {...} // getters['account/isAdmin'] } } } })
對於內部模塊,若是你但願獲取全局的state和getter,能夠經過rootState、rootGetter獲取到
若須要在全局命名空間內分發action或者提交mutation,將{root: true}做爲第三個參數傳給dispatch或者commit便可
// 在另一個模塊獲取cart模塊 rootState.cart.all dispatch('someOtherAction', null, { root: true }) // -> 'someOtherAction' commit('someMutation', null, { root: true }) // -> 'someMutation'