學習目的
? ? 了解和熟練使用 VueX,能夠在實際項目中運用。
VueX介紹
????Vuex 是一個專為 Vue.js 應用程序開發的狀態管理模式。它采用集中式存儲管理應用的所有組件的狀態,并以相應的規則保證狀態以一種可預測的方式發生變化。
? ? ? ? 所有組件的狀態,簡單來講,就是 data 里的屬性,如果有多個組件 需要使用同一個數據,使用 props 會顯得很復雜,尤其是非父子組件 和 父組件和后代組件 之間的數據傳輸問題,這時候就可以用到 VueX。
? ? ? ? 使用場景
? ? ? ? ?問題1:多個視圖依賴于同一狀態。
? ? ? ? 問題2:來自不同視圖的行為需要變更同一狀態。
? ? ? ? ?對于問題一,傳參的方法對于多層嵌套的組件將會非常繁瑣,并且對于兄弟組件間的狀態傳遞無能為力。對于問題二,我們經常會采用父子組件直接引用或者通過事件來變更和同步狀態的多份拷貝。以上的這些模式非常脆弱,通常會導致無法維護的代碼。
????????因此,我們為什么不把組件的共享狀態抽取出來,以一個全局單例模式管理呢?在這種模式下,我們的組件樹構成了一個巨大的“視圖”,不管在樹的哪個位置,任何組件都能獲取狀態或者觸發行為!
????????但是 官方推薦,不要為了使用 VueX 而去使用 VueX。官方推薦:
? ??????如果您不打算開發大型單頁應用,使用 Vuex 可能是繁瑣冗余的。確實是如此——如果您的應用夠簡單,您最好不要使用 Vuex。一個簡單的?global event bus?就足夠您所需了。但是,如果您需要構建一個中大型單頁應用,您很可能會考慮如何更好地在組件外部管理狀態,Vuex 將會成為自然而然的選擇。
? ? ? ?VueX安裝
? ? ? ? ? ? ? ?① npm install vuex --save-dev
? ? ? ? ? ? ? ?② 新建文件
? ? ? ? ? ? ? ? ③ 在 index.js 里
? ? ? ? ? ? ? ? ④ 在入口文件main.js 引入
? ? ? ? ? ? ? ? ⑤ 試用
? ??????VeuX 核心
? ? ? ? ? ? ? ? ? State
? ? ? ? ? ? ? ? ? ?state 訪問狀態對象,就是? 所有組件 共享的數據。
? ????????????Vuex 的狀態存儲是響應式的。當 Vue 組件從 store 中讀取狀態的時候,若 store 中的狀態發生變化,那么相應的組件也會相應地得到高效更新。
? ? ? ? ? ? ? ?不能直接改變 store 中的狀態(就像 this.$store.state.XXX = XXXX)。改變 store 中的狀態的唯一途徑就是顯式地提交 (commit) mutation。這樣使得我們可以方便地跟蹤每一個狀態的變化,從而讓我們能夠實現一些工具幫助我們更好地了解我們的應用。
? ? ? ? ? ? ? ? ? ? 有以下幾種方式 在組件中使用 state:
? ? ? ? ? ? ? ? ? ? ① 直接用 {{ }} + $store.state.XXXX
? ? ? ? ? ? ? ? ? ? ② 通過computed的計算屬性直接賦值
? ? ? ? ? ? ? ? ? ? ③?通過?mapState?的對象來賦值
? ? ? ? ? ? ? ? ? ? ? ? ④ 通過 mapState 的數組來賦值(最常用)
? ??????????????????????當映射的計算屬性的名稱與 state 的子節點名稱相同時,我們也可以給?mapState?傳一個字符串數組。
? ? ? ? ? ? ? ? ? ?Getters
? ??????????????????可以認為是 store 的計算屬性
? ? ? ? ? ? ? ? ? ? ? ?使用 getter 的幾種方式
? ? ? ? ? ? ? ? ? ? ? ? ? ? 記住? ?import { mapGetters } from 'vuex'
? ? ? ? ? ? ? ? ? ? Mutations(mutation 必須是同步函數)
????????????更改 Vuex 的 store 中的狀態的唯一方法是提交 mutation。Vuex 中的 mutation 非常類似于事件:每個 mutation 都有一個字符串的?事件類型 (type)?和 一個?回調函數 (handler)。這個回調函數就是我們實際進行狀態更改的地方,并且它會接受 state 作為第一個參數:
? ??????????????? ????可以認為是?store 的 methods
? ? ? ? ? ? ? ? ? ???Mutations的回調函數接收第二個參數,一般是一個對象
? ? ? ? ? ? ? ? ? ? ? ? ? ? 第二個參數為對象的使用情況
Mutation 需遵守 Vue 的響應規則:
? ? ? 1.? 最好提前在你的 store 中初始化好所有所需屬性(上圖的注冊 text)
? ? ? ? ? ? 在組件的methods中?
? ??????????????將 `this.add()` 映射為 `this.$store.commit('add')`
? ???????????????將 `this.reduce()` 映射為 `this.$store.commit('reduce')`
? ??????????????????Actions
? ? ? ? ? ? ? ? ?Action 類似于 mutation,不同在于:Action 提交的是 mutation,而不是直接變更狀態。Action 可以包含任意異步操作。
? ???????????????Action 函數接受一個與 store 實例具有相同方法和屬性的 context 對象,因此你可以調用?context.commit?提交一個 mutation,或者通過?context.state?和?context.getters?來獲取 state 和 getters。
? ? ? ? ? ? 也可以只直接在組件中使用 this.$stroe.dispathc( ' addAction' )
? ? ? ? ? ? 更多關于actions的異步操作的情況,可以參考官網上的例子。
? ??????????????????Module
????????????????由于使用單一狀態樹,應用的所有狀態會集中到一個比較大的對象。當應用變得非常復雜時,store 對象就有可能變得相當臃腫。為了解決以上問題,Vuex 允許我們將 store 分割成模塊(module)。每個模塊擁有自己的 state、mutation、action、getter、甚至是嵌套子模塊——從上至下進行同樣方式的分割,便于維護。
? ? ? ? ? ? ? ? ? ? ? ? 默認情況下,模塊內部的 action、mutation 和 getter 是注冊在全局命名空間的——這樣使得多個模塊能夠對同一 mutation 或 action 作出響應。
? ? ? ? ? ? ? ? ? ? ? ?如果希望你的模塊具有更高的封裝度和復用性,你可以通過添加?namespaced: true?的方式使其成為帶命名空間的模塊。當模塊被注冊后,它的所有 getter、action 及 mutation 都會自動根據模塊注冊的路徑調整命名。【模塊名/函數名】
? ??????????????????????Module更多用法請參考官網? ?VueX 文檔??