首先Vuex
是Vue
'全家桶'的成員之一,也是一個專爲Vue.js
應用程序開發的狀態管理模式。 官方說法: 它採用集中式存儲管理應用的全部組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。javascript
由於組件之間是相互獨立的,組件之間想要通訊。其中有經過props
選項通訊,但這隻限於父子組件通訊,遠遠不能知足組件之間通訊的需求,特別是作中大型的項目。因此就把組件之間須要共享的數據給單獨'弄'出來。 經過定義和隔離狀態管理中的各類概念並經過強制規則維持視圖和狀態間的獨立性,咱們的代碼將會變得更結構化且易維護。vue
Vuex能夠幫助咱們管理共享狀態,並附帶了更多的概念和框架,這須要對短時間和長期效益進行權衡。 若是不是開發中大型單頁應用,使用Vuex多是繁瑣冗餘的,不建議使用。java
每個 Vuex
應用的核心就是 store
(倉庫)。「store」基本上就是一個容器,它包含着你的應用中大部分的狀態 (state)。Vuex 和單純的全局對象有如下兩點不一樣:vuex
Vuex 的狀態存儲是響應式的。當 Vue 組件從 store 中讀取狀態的時候,若 store 中的狀態發生變化,那麼相應的組件也會相應地獲得高效更新。緩存
你不能直接改變 store 中的狀態。改變 store 中的狀態的惟一途徑就是顯式地提交 (commit) mutation。這樣使得咱們能夠方便地跟蹤每個狀態的變化,從而讓咱們可以實現一些工具幫助咱們更好地瞭解咱們的應用。框架
state
: 把組件須要通訊的數據定義在store
的state
中。容器的狀態(響應式數據,能夠觸發視圖更新的數據)。 舉例:異步
//若是在模塊化構建系統中,請確保在開頭調用了 Vue.use(Vuex)
//視圖狀態倉庫中(超大的ViewModel,把須要跨組件通訊的數據都放到這裏)
const store = new Vuex.Store({
//容器狀態(響應式數據,能夠觸發視圖更新的數據)
state: {
count: 0
},)
//在組件中經過計算屬性來獲取 store.state中的成員
Vue.component('component-b', {
template: ` <div> componentB <h1>{{count }}</h1> </div> `,
created () {
},
data () {
return {
}
},
computed: { //使用computed 來監視count的變化,當count的值一變化,就會調用computed的事件
count () {
return store.state.count
}
}
})
複製代碼
getter
: 就像計算屬性同樣,getter
的返回值會根據它的依賴被緩存起來,且只有當它的依賴值發生了改變纔會被從新計算。 舉例:模塊化
const store = new Vuex.Store({
state: {
todos: [
{ name: '小張',compoleted: true},
{ name: '小李',compoleted: false }
]
},
getters: {
compoletedTodos: state => { //getter 接受state做爲其第一個參數
return state.todos.filter (todo => toto.compoleted)
},
comTodosLength: ( state, getters) => { //getter 也能夠接受其餘的getter做爲第二個參數
return getters.compoletedTodos.length
}
}
})
經過屬性訪問
store.getters.compoletedTodos
複製代碼
mutation
: 它是更改Vuex
的store
中的狀態的惟一方法,很是相似於事件,每一個mutation
都有一個字符串的事件類型type
和一個回調函數handle
。 舉例:函數
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
increment (state) {
// 變動狀態
state.count++
}
}
})
在組件中經過store.commit方法來觸發mutation
store.commit('increment ')
複製代碼
經過store.commit
傳入額外的參數,即mutation
的載荷(payload
): 舉例:工具
方式一:
mutations: {
increment (state,n) {
state.count += n
}
}
store.commit('increment',10)
方式二: 載荷應該是一個對象
mutations: {
increment (state,payload) {
state.count += payload.amount
}
}
store.commit('increment',{
amount: 10
})
方式三:對象風格的提交方式,可是定義mutation函數保持不變
store.commit({
type:'increment',
amunt: 10
})
複製代碼
action
: action
相似於 mutation
,可是不一樣的是:
action
提交的是mutation
,而不是直接變動狀態。action
能夠包含任何異步操做 舉例:const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
//action 函數接受一個與store實例具備相同方法和屬性的context對象
increment (context) {
context.commit('increment')
}
}
})
複製代碼
action
經過 store.dispatch
觸發:
store.dispatch('increment')
複製代碼
action
與mutation
最大的不一樣是:mutation
必須同步執行,而action
就不受約束,能夠在action
內部執行異步操做:
actions: {
incrementAsync ({ commit }) {
setTimeout(() => {
commit('increment')
}, 1000)
}
}
複製代碼
action
支持一樣的載荷方式和對象方式進行分發。 module
: 當項目很是大的時候,應用的全部狀態會集中到一個比較大的對象,store
對象就有可能變得至關臃腫。 爲了解決以上問題,咱們能夠將store
分割成模塊,同時每一個模塊擁有本身的state
,mutation
,action
,getter
,還能嵌套子模塊,從上至下進行一樣方式的分割。
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 的狀態
複製代碼
mapState
輔助函數mapGetters
輔助函數mapMutations
輔助函數mapActions
輔助函數Vuex
還有不少知識點,尤大神已經寫的很全面了,你們感興趣的能夠參考Vuex
(vuex.vuejs.org/zh/)的官網。