Vuex 是一個專爲 Vue.js 應用程序開發的狀態管理模式。它採用集中式存儲管理應用的全部組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。vue
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
使用 Vuex 開發大型單頁應用是很是合適的。若是的應用夠簡單,最好不要使用 Vuex。vuex
Vuex 的特性:緩存
Vuex 的狀態存儲是響應式的。當 Vue 組件從 store 中讀取狀態的時候,若 store 中的狀態發生變化,那麼相應的組件也會相應地獲得高效更新。異步
你不能直接改變 store 中的狀態。改變 store 中的狀態的惟一途徑就是顯式地提交 (commit) mutation。 函數
Vuex 的狀態存儲是響應式的,從 store 實例中讀取狀態最簡單的方法就是在計算屬性中返回某個狀態this
每個 Vuex 應用的核心就是 store(倉庫)。「store」基本上就是一個容器,它包含着你的應用中大部分的狀態 (state)。atom
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
}
})
能夠經過 store.state 來獲取狀態對象,以及經過 store.commit 方法觸發狀態變動:spa
store.commit('increment')
console.log(store.state.count)
Vuex 使用單一狀態樹——是的,用一個對象就包含了所有的應用層級狀態。組件能夠經過 this.$store.state 來訪問須要用到的數據狀態。對象
Getter 能夠認爲是 store 的計算屬性。就像計算屬性同樣,getter 的返回值會根據它的依賴被緩存起來,且只有當它的依賴值發生了改變纔會被從新計算。在組件中能夠經過 store.getter 來訪問。blog
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
getters: {
doneTodos: state => { //state 做爲第一個參數
return state.todos.filter(todo => todo.done)
},
doneTodosCount: (state, getters) => { //其餘的 getter 做爲第二個參數
return getters.doneTodos.length
}
}
})
更改 Vuex 的 store 中的狀態的惟一方法是提交 mutation。每一個 mutation 都有一個字符串的 事件類型 (type) 和 一個 回調函數 (handler)。這個回調函數就是咱們實際進行狀態更改的地方,而且它會接受 state 做爲第一個參數
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
increment (state, payload) {
state.count += payload.amount
}
}
})
store.commit('increment', { //提交mutation的第一種方式
amount: 10
})
store.commit({ //提交mutation的第二種方式
type: 'increment',
amount: 10
})
mutation 使用注意事項:
最好提早在你的 store 中初始化好全部所需屬性。
當須要在對象上添加新屬性時,你應該
使用 Vue.set(obj, 'newProp', 123), 或者
以新對象替換老對象。例如,利用 stage-3 的對象展開運算符咱們能夠這樣:state.obj = {
Mutation 必須是同步函數
Action 相似於 mutation,不一樣在於:
Action 提交的是 mutation,而不是直接變動狀態。
Action 能夠包含任意異步操做。
Action 函數接受一個與 store 實例具備相同方法和屬性的 context 對象,所以你能夠調用 context.commit 提交一個 mutation,或者經過 context.state 和 context.getters 來獲取 state 和 getters。
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment')
}
}
})
store.dispatch('increment')
Vuex 容許咱們將 store 分割成
onst moduleA = {
state: {
對於模塊內部的 mutation 和 getter,接收的第一個參數是模塊的局部狀態對象。
對於模塊內部的 action,局部狀態經過 context.state 暴露出來,根節點狀態則爲 context.rootState
模塊內部的 action、mutation 和 getter 默認是註冊在全局命名空間的,可是經過添加 namespaced: true 的方式可使其成爲帶命名空間的模塊。
modules: { foo: { namespaced: true, getters: { // getter 的第一個參數 `state` // getter 的第二個參數 `getters` // getter 的第三個參數 `rootState` // getter 的第四個參數 `rootGetters` someGetter (state, getters, rootState, rootGetters) { getters.someOtherGetter // -> 'foo/someOtherGetter' rootGetters.someOtherGetter // -> 'someOtherGetter' }, someOtherGetter: state => { ... } }, actions: { // action 的第一個參數 `dispatch` // action 的第二個參數 `commit` // action 的第三個參數 `getters` // action 的第四個參數 `rootGetters` someAction ({ dispatch, commit, getters, rootGetters }) { getters.someGetter // -> 'foo/someGetter' rootGetters.someGetter // -> 'someGetter' dispatch('someOtherAction') // -> 'foo/someOtherAction' dispatch('someOtherAction', null, { root: true }) // -> 'someOtherAction' commit('someMutation') // -> 'foo/someMutation' commit('someMutation', null, { root: true }) // -> 'someMutation' }, someOtherAction (ctx, payload) { ... } } } }
在 store 建立以後,你可使用 store.registerModule 方法註冊模塊:
// 註冊模塊 `myModule`
store.registerModule('myModule', {
// ...
})
// 註冊嵌套模塊 `nested/myModule`
store.registerModule(['nested', 'myModule'], {
// ... })