對於初學者,學vue簡單,可是當第一次遇到Vuex概念的時候,理解難度每每驟然陡峭,會讓人感到挫敗感,挫敗感來自於大多數教程文章用了大量篇幅來介紹Vuex較爲複雜,卻看完感受沒什麼做用(不知道如何運用)的實現模式,本文就是要簡而化之,讓你秒懂。vue
Vuex 術語定義叫作『全局狀態管理』,其實質就是一個全局變量,能夠供不一樣組件間調用,更新,自動通知。 固然在具體實現的時候,這個全局變量實際上是一個全局對象:this.$store
,ios
因此記住這個store對象,它就是vuex。vuex
facebook之前在搞他的那個網頁app的時候,尤爲是在作消息模塊的時候,各類全局通知和聊天信息,組件間互相通訊很是混亂,老出bug,因而他們就發明了一種解決這個問題的設計模式,叫作 FLUX。axios
這個設計模式是按照怎樣的原則來解決通訊混亂的問題呢?設計模式
也就是說,store是一個惟一全局變量(對象),不能搞多個,搞多個就亂了。bash
這個只讀不是說徹底不讓讀,而是不能讓 store外部直接操做數據,必須經過store內部方法(mutations)來操做數據。app
異步數據會很混亂,必須是同步操做模式。異步
爲何是這3個原則,你不用管,反正facebook反覆實驗,按照這三個原則設計,問題就搞定了。函數
facebook 按照FLUX設計模式,開發了大名鼎鼎的Redux庫,React必備搭配。Vue看見此需求羣衆呼聲很高,也配套了一個,也就是Vuex。post
因此,Redux和Vuex都是對Flux這種設計模式的實現,別混爲一談。
store 這個對象,確定是掛載Vue上面的,就是按照下面這種方式掛:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
},
actions: {
},
mutations: {
},
getters: {
},
modules: {
}
})
export default store
複製代碼
咱們看到有這些 state,actions,mutations,modules這些屬性, 爲啥一個實質是變量的對象搞這麼複雜,這其實和Flux設計模式有關係,它的本質就是:「個人事情我本身來,大家(組件)別直接操做我,告訴我就行,我本身來」。
下面一個一個講:
state,這個所謂的狀態,其實就是數據,全局的數據。
你在一個vue組件裏,這樣寫,就能夠獲取這個數據:
computed: {
count () {
return this.$store.state.count
}
}
複製代碼
這個count就是state下面定義的一個數據,怎麼定義的呢:
const store = new Vuex.Store({
state: {
count: 0
}
})
複製代碼
在那個掛載store對象的文件裏,這樣定義,很是符合直覺。 你這邊寫0,上面那邊就讀出0,你這邊改爲2了,上面就自動變成2,監聽是默認的。
接着上面講,你怎麼把count改爲2呢?
this.$store.state.count = 2
複製代碼
這樣是不行的,前面講過,你不要直接動store的數據,你須要告訴它,讓他本身來處理。
因此store本身先得有個處理方法,這就是mutations:
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
}
})
複製代碼
這個方法就是increment,很符合直覺。
你在組件那裏要作就是通知store,激活這個increment,怎麼寫呢:
this.$store.commit('increment')
複製代碼
注意,講到這裏,單詞愈來愈多了,英語很差的同窗須要記住對應關係,commit就是觸發一個事件,通知store執行mutations下的某個方法。
Vue 組件下面有個computed屬性,一個組件本身用沒問題,若是多個組件下都想使用一個共有的computed屬性,那麼這就是 store裏面的getters。
唉,英語很差真傷心啊,起那麼多名字實際上是一個東西。
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
}
}
})
複製代碼
看到沒,上面getters動態屬性doneTodos,就是拿state靜態屬性todos放進一個函數算了一遍。
actions很簡單,就是異步的mutations,咦?不對啊,前面咱們講flux三原則的時候,說過數據更新必須是同步的,這個仍是英文的問題,Mutations Are Synchronous,說的是mutation,可是有時候咱們須要異步去請求數據,這個時候就須要actions。
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment:function ({ commit }) {
axios.get('/add').then((response) => {
commit('increment')
}, (err) => {
console.log(err)
})
}
})
複製代碼
怎麼觸發actions裏的increment呢?
this.$store.dispatch('increment')
複製代碼
個人天,又多了一個單詞:dispatch, 知道爲啥新手會以爲困難了吧?
官方文檔給的那個示例其實不是很好,官方只是說action必須commit,但理解actions的關鍵在於它的使用場景是異步,由於flux的實質是同步,因此異步拿到數據後,必須經過mutation去更新數據,因此必須commit;
不少組件都共用store裏面state來存數據,組件多了,時間久了,不利於管理。 因而就有這個modules模塊
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`'s state store.state.b // -> `moduleB`'s state
複製代碼
主要觀察
modules: {
a: moduleA,
b: moduleB
}
複製代碼
在調用的時候,就能夠分別調用
store.state.a // -> `moduleA`'s state store.state.b // -> `moduleB`'s state
複製代碼
看完這篇文章,你再去看官方文檔,應該沒問題了,可是若是我把官方文檔的例子和其餘信息全搬過來,你確定會暈。
vuex很簡單,難就難在那幾個設計原則你不知道,還有就是單詞有點多,記不過來。
看完文檔後,你實驗幾回就知道怎麼運用了。