讓咱們從一個簡單的計數器,開始進入Vuex 的世界:vue
計數器應用的數據模型很簡單:使用一個counter屬性來表示計數器的 當前值就夠了。git
在Vue實例的created鉤子 中,應用啓動了一個定時器,用來週期性地 遞增counter屬性的值 —— 因爲counter是響應式屬性,它的變化於是 驅動了視圖隨之刷新。github
能夠說counter抽象地表達了計數器視圖的本質特徵,當counter的 值肯定時,咱們能夠肯定地推理出視圖的表現。像counter這樣能夠決定 視圖表現的數據,在Vuex中就被稱爲狀態。vuex
計數器應用至關簡單,所以咱們只須要定義一個狀態就能夠了。稍微複雜 一些的應用,則可能須要咱們抽象出成百上千的狀態,這時候就須要分類 管理了。異步
例如,對於一個電商應用,咱們將其購物車相關的狀態納入cart類:async
你看到,應用的所有狀態,構成了一棵層級分明的狀態樹。而Vuex的做用 ,就在於管理一個應用的狀態樹。模塊化
Vuex進行應用狀態管理 的第一個手段,是要求應用創建並維護一個單一的、全 應用範圍共享的狀態樹,而不是各個組件單獨維護本身的狀態(在組件中使用data配置項聲明) —— 不過這不是絕對的,那些徹底不須要在多個組件間 共享的狀態,依然能夠在組件內部聲明。學習
出於學習的目的,同時爲了不引入複雜的演示代碼,咱們假設計數器的counter狀態須要與其餘組件共享,所以咱們將其定義遷移到狀態樹中。spa
建立狀態庫設計
Vuex的Store類 —— 狀態庫 —— 用於管理狀態樹,它的實例化配置項state用來聲明要建立的狀態樹。例如,下面的代碼建立了一個包含狀態counter的 狀態庫:
conststore =newVuex.Store( { state:{ counter:0} } )
利用狀態庫的state屬性,就能夠訪問到其管理的狀態樹了。例如,經過store.state.counter來訪問counter狀態。
須要指出的是,狀態庫的state屬性 —— 狀態樹 —— 是一個響應式屬性,所以 咱們可使用狀態樹上的這些狀態來驅動視圖的自動更新。
使用計算屬性訪問狀態樹
在創建了全應用單一狀態樹以後,接下來咱們要考慮的就是在組件中怎麼使用 樹上的狀態了 —— 咱們已經決定不聲明組件的私有狀態。
最簡單的方法是將樹上的狀態,映射爲組件的計算屬性。例如,下面的代碼將 狀態樹上的counter狀態,映射爲組件的可讀寫計算屬性:
constEzCounter = { template:'{ {counter} }', computed:{ counter:{ get() {returnstore.state.counter }, set(v){ store.state.counter = v } } } }
將狀態庫注入組件
另外一種方法是將狀態庫掛接爲Vue實例的一個屬性上,這樣咱們就能夠在模板中 直接訪問狀態樹了(模板的上下文對象是所屬的Vue實例)。
在建立Vue實例時,使用store配置項,就能夠將狀態庫掛接爲Vue實例 的屬性$store,並且這個Vue實例的全部後代實例,也都有$store指向 同一個狀態庫,看起來就像是將狀態庫注入了組件樹上的每個實例。
例如,下面的代碼使用store配置項,將狀態庫store注入根組件,所以 咱們能夠在EzCounter組件中利用$store屬性訪問狀態庫:
const EzCounter = { template:'{{$store.state.counter}}' } new Vue({ store:store, template:'', components:{EzCounter} })
Vuex進行狀態管理 的第二個手段,是承擔起管理狀態變動(mutation)的 責任。
Vuex要求組件將狀態樹視爲只讀,組件不該該直接修改狀態樹上的狀態, 而是經過提申請的方式,由狀態庫來實際執行狀態變動的操做:
對於計數器應用來說,修改counter狀態的需求有兩個:遞增和復位。 所以,咱們須要首先在狀態庫中聲明兩個變動處理器(mutation handler)。
在建立狀態庫時,使用mutations配置項來聲明變動處理器。例如,下面 的代碼爲狀態庫聲明瞭兩個變動處理器:INCREASE和RESET:
conststore =newVuex.Store({ state:{counter:0}, mutations:{ INCREASE:state=>state.counter++ , RESET:state=>state.counter =0 } })
Vuex推薦使用大寫字母來命名變動處理器,由於這個名字也將做爲 組件提交的變動請求的類型名 —— 從組件的角度看,還有比大寫的名字 更能表達出這是一個請求而不是實際操做嗎 —— 回憶一下Windows 的WM_系列消息的名字。
狀態變動處理器(mutation handler)的參數是一個局部上下文 (local context)對象的state屬性,咱們須要利用這個參數來 更新狀態樹上指定的狀態。局部上下文是Vuex爲實現狀態樹的模塊化管 理而構造的狀態庫局部鏡像,咱們將在《模塊化管理》章節詳細講解 局部上下文(local context)對象。如今,就把它暫時理解爲原始的 狀態庫好了。
提交變動請求
組件應當調用狀態庫的commit()方法來提交指定類型的狀態變動請求。 例如,下面的代碼向狀態庫提交了遞增counter狀態的申請:
store.commit('INCREASE')
Vuex進行狀態管理 的第三個手段,是要求應用保證狀態變動(mutation)的 同步性 —— 狀態變動處理器執行完之時,狀態更新必定要完成。
這意味着,在狀態變動處理器裏不能執行異步代碼。這一要求直接致使了新的 環節的引入 —— 狀態動做(action):
根據做者的說法(原文參見:About mutations usefulness), 引入狀態動做(action)這一環節的惟一目的,就是爲了保證狀態變動(mutation) 的同步性:"Actions vs. mutations is all about separating asynchronicity from actual mutations"
狀態動做(action)隔離了組件和狀態庫,組件如今應當分發執行狀態庫聲明的動做, 而後由狀態動做負責提交變動請求。
在建立狀態庫時,使用actions配置項聲明狀態動做。例如,下面的代碼 聲明瞭兩個狀態動做inc和reset,分別用來提交INCREASE和RESET變動 請求:
conststore =newVuex.Store({ state:{counter:0}, mutations:{INCREASE:state=>state.counter++,RESET:state=>state.counter =0}, actions:{inc:context=>context.commit('INCREASE'), reset:context=>context.commit('RESET') } })
狀態動做(action handler)的參數是一個局部上下文(local context)對象, 咱們已經知道它是Vuex爲模塊構造的狀態庫局部鏡像,所以調用它的commit()方法, 就能夠提交變動請求了。
分發執行狀態動做
調用狀態庫的dispatch()方法來分發執行指定名稱的狀態動做。例如, 下面的代碼要求狀態庫執行inc動做:
store.dispatch('inc')
更多關於vuex的精彩內容請到這裏來: