在 Vue 的單頁面應用中使用,須要使用Vue.use(Vuex)
調用插件。
使用很是簡單,只須要將其注入到Vue根實例中。javascript
import Vuex from 'vuex' Vue.use(Vuex) const store = new Vuex.Store({ state: { count: 0 }, getter: { doneTodos: (state, getters) => { return state.todos.filter(todo => todo.done) } }, mutations: { increment (state, payload) { state.count++ } }, actions: { addCount(context) { // 能夠包含異步操做 // context 是一個與 store 實例具備相同方法和屬性的 context 對象 } } }) // 注入到根實例 new Vue({ el: '#app', store, template: '<App/>', components: { App } })
而後改變狀態:vue
this.$store.commit('increment')
Vuex 主要有四部分:java
store
中存儲的各個狀態。store
中狀態的執行者。Vuex 使用 state
來存儲應用中須要共享的狀態。爲了能讓 Vue 組件在 state
更改後也隨着更改,須要基於state
建立計算屬性。vuex
const Counter = { template: `<div>{{ count }}</div>`, computed: { count () { return this.$store.state.count // count 爲某個狀態 } } }
相似於 Vue 中的 計算屬性,能夠在因此來的其餘 state
或者 getter
改變後自動改變。
每一個getter
方法接受 state
和其餘getters
做爲前兩個參數。數組
getters: { doneTodos: (state, getters) => { return state.todos.filter(todo => todo.done) } }
前面兩個都是狀態值自己,mutations
纔是改變狀態的執行者。mutations
用於同步地更改狀態promise
// ... mutations: { increment (state, n) { state.count += n } }
其中,第一個參數是state
,後面的其餘參數是發起mutation
時傳入的參數。app
this.$store.commit('increment', 10)
commit
方法的第一個參數是要發起的mutation
名稱,後面的參數均當作額外數據傳入mutation
定義的方法中。
規範的發起mutation
的方式以下:異步
store.commit({ type: 'increment', amount: 10 //這是額外的參數 })
額外的參數會封裝進一個對象,做爲第二個參數傳入mutation
定義的方法中。async
mutations: { increment (state, payload) { state.count += payload.amount } }
想要異步地更改狀態,須要使用action
。action
並不直接改變state
,而是發起mutation
。函數
actions: { incrementAsync ({ commit }) { setTimeout(() => { commit('increment') }, 1000) } }
發起action
的方法形式和發起mutation
同樣,只是換了個名字dispatch
。
// 以對象形式分發 store.dispatch({ type: 'incrementAsync', amount: 10 })
想要使用action
處理異步工做很簡單,只須要將異步操做放到action
中執行(如上面代碼中的setTimeout
)。
要想在異步操做完成後繼續進行相應的流程操做,有兩種方式:
action
返回一個 promise
。dispatch
方法的本質也就是返回相應的action
的執行結果。因此dispatch
也返回一個promise
。
store.dispatch('actionA').then(() => { // ... })
2. 利用async/await
。代碼更加簡潔。
// 假設 getData() 和 getOtherData() 返回的是 Promise actions: { async actionA ({ commit }) { commit('gotData', await getData()) }, async actionB ({ dispatch, commit }) { await dispatch('actionA') // 等待 actionA 完成 commit('gotOtherData', await getOtherData()) } }
將state
和getter
結合進組件須要使用計算屬性:
computed: { count () { return this.$store.state.count // 或者 return this.$store.getter.count2 } }
將mutation
和action
結合進組件,須要在methods
中調用this.$store.commit()
或者this.$store.commit()
:
methods: { changeDate () { this.$store.commit('change'); }, changeDateAsync () { this.$store.commit('changeAsync'); } }
爲了簡便起見,Vuex 提供了四個方法用來方便的將這些功能結合進組件。
mapState
mapGetters
mapMutations
mapActions
示例代碼:
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex' // .... computed: { localComputed () { /* ... */ }, ...mapState({ // 爲了可以使用 `this` 獲取局部狀態,必須使用常規函數 count(state) { return state.count + this.localCount } }), ...mapGetters({ getterCount(state, getters) { return state.count + this.localCount } }) } methods: { ...mapMutations({ add: 'increment' // 將 `this.add()` 映射爲`this.$store.commit('increment')` }), ...mapActions({ add: 'increment' // 將 `this.add()` 映射爲 `this.$store.dispatch('increment')` }) }
若是結合進組件以後不想改變名字,能夠直接使用數組的方式。
methods: { ...mapActions([ 'increment', // 將 `this.increment()` 映射爲 `this.$store.dispatch('increment')` // `mapActions` 也支持載荷: 'incrementBy' // 將 `this.incrementBy(amount)` 映射爲 `this.$store.dispatch('incrementBy', amount)` ]), }
store
分割爲模塊。能夠將應用的store
分割爲小模塊,每一個模塊也都擁有全部的東西:state
, getters
, mutations
, actions
。
首先建立子模塊的文件:
// initial state const state = { added: [], checkoutStatus: null } // getters const getters = { checkoutStatus: state => state.checkoutStatus } // actions const actions = { checkout ({ commit, state }, products) { } } // mutations const mutations = { mutation1 (state, { id }) { } } export default { state, getters, actions, mutations }
而後在總模塊中引入:
import Vuex from 'vuex' import products from './modules/products' //引入子模塊 Vue.use(Vuex) export default new Vuex.Store({ modules: { products // 添加進模塊中 } })
其實還存在命名空間的概念,大型應用會使用。須要時查看文檔便可。Vuex的基本使用大體如此。