Vuex快速入門

文檔在這里: Vuex (vuejs.org)

1. Vuex 是什么?

Vuex 是一個專為 Vue.js 應用程序開發(fā)的狀態(tài)管理模式幌衣。它采用集中式存儲管理應用的所有組件的狀態(tài),并以相應的規(guī)則保證狀態(tài)以一種可預測的方式發(fā)生變化碗殷。
狀態(tài)管理模式
讓我們從一個簡單的 Vue 計數(shù)應用開始:

new Vue({
  // state
  data () {
    return {
      count: 0
    }
  },
  // view
  template: `
    <div>{{ count }}</div>
  `,
  // actions
  methods: {
    increment () {
      this.count++
    }
  }
})

這個狀態(tài)自管理應用包含以下幾個部分:

  • state,驅動應用的數(shù)據(jù)源速缨;
  • view锌妻,以聲明方式將 state 映射到視圖;
  • actions旬牲,響應在 view 上的用戶輸入導致的狀態(tài)變化仿粹。

以下是一個表示“單向數(shù)據(jù)流”理念的簡單示意:

image.png

然而當多個組件共享狀態(tài)(也就是數(shù)據(jù))的時候,數(shù)據(jù)變動的來源變得不明顯原茅,邏輯變得繁瑣不清晰吭历。那么 vuex 就是將組件的共享狀態(tài)抽取出來,以一個全局單例模式來管理的员咽,專門為 Vue.js 設計的狀態(tài)管理庫毒涧,它利用 Vue.js 的細粒度數(shù)據(jù)響應機制來進行高效的狀態(tài)更新。
vuex

通俗地來講贝室,就是當頁面應用過多且復雜契讲,這個時候就適合用 vuex 在組件外部管理狀態(tài)。

2. 安裝

直接下載

npm install vuex --save
// npm 或 yarn
yarn add vuex

// 在一個模塊化的打包系統(tǒng)中滑频,必須顯式地通過 Vue.use() 來安裝 Vuex
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

CDN 引用
當使用全局 script 標簽引用 Vuex 時捡偏,不需要以上安裝過程。

<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/vuex"></script>

3. State

創(chuàng)建一個 store峡迷,創(chuàng)建過程直截了當——僅需要提供一個初始 state 對象和一些 mutation:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  }
})

現(xiàn)在银伟,可以通過 store.state 來獲取狀態(tài)對象,以及通過 store.commit 方法觸發(fā)狀態(tài)變更:

store.commit('increment')
console.log(store.state.count) // -> 1

mapState函數(shù)
mapState 函數(shù)返回的是一個對象绘搞。它可以將多個對象合并為一個彤避,以使我們可以將最終對象傳給 computed 屬性。

image.png

其中 ... 叫做 對象擴展運算符夯辖,可以將 mapState 返回的對象展開在所在位置上琉预。

4. Getters

Vuex 允許我們在 store 中定義“getter”(可以認為是 store 的計算屬性)。就像計算屬性一樣蒿褂,getter 的返回值會根據(jù)它的依賴被緩存起來圆米,且只有當它的依賴值發(fā)生了改變才會被重新計算。
Getter 接受 state 作為其第一個參數(shù)啄栓,如果需要的話也可以接受其他 getter 作為第二個參數(shù)娄帖。

image.png

實例中的 fullName() 函數(shù)可以換成 ...Vuex.mapGetters(['fullName'])

5. Mutation

更改 Vuex 的 store 中的狀態(tài)的唯一方法是提交 mutation。Vuex 中的 mutation 非常類似于事件:每個 mutation 都有一個字符串的 事件類型 (type) 和 一個 回調函數(shù) (handler)昙楚。這個回調函數(shù)就是我們實際進行狀態(tài)更改的地方近速。
在上面的兩個例子之中已經使用到了 mutation 。
還可以向 mutation 傳入額外的參數(shù),當然也可以傳遞一個對象数焊。

// ...
mutations: {
  increment (state, n) {
    state.count += n
  }
}
store.commit('increment', 10)

Mutation 需遵守 Vue 的響應規(guī)則

  1. 需要提前在 store 中初始化好所有所需屬性永淌。
  2. 當需要在對象上添加新屬性時,你應該
  • 使用 Vue.set(obj, 'newProp', 123), 或者
  • 以新對象替換老對象佩耳。

Mutation 必須是同步函數(shù)
每一條 mutation 都會被記錄遂蛀,如果使用異步,在 devtools 上將會很難捕捉前一狀態(tài)與后一狀態(tài)的快照干厚。(實質上任何在回調函數(shù)中進行的狀態(tài)的改變都是不可追蹤的)
在組件中提交 Mutation
可以在組件中使用 this.$store.commit('xxx') 提交 mutation李滴,或者使用 mapMutations 輔助函數(shù)將組件中的 methods 映射為 store.commit 調用(需要在根節(jié)點注入 store)。

import { mapMutations } from 'vuex'

export default {
  // ...
  methods: {
    ...mapMutations([
      'increment', // 將 `this.increment()` 映射為 `this.$store.commit('increment')`

      // `mapMutations` 也支持載荷:
      'incrementBy' // 將 `this.incrementBy(amount)` 映射為 `this.$store.commit('incrementBy', amount)`
    ]),
    ...mapMutations({
      add: 'increment' // 將 `this.add()` 映射為 `this.$store.commit('increment')`
    })
  }
}

6. Action

Action 類似于 mutation蛮瞄,不同在于:

  • Action 提交的是 mutation所坯,而不是直接變更狀態(tài)。
  • Action 可以包含任意異步操作挂捅。
    讓我們來注冊一個簡單的 action:
const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {
    increment (context) {
      context.commit('increment')
    }
  }
})

Action 函數(shù)接受一個與 store 實例具有相同方法和屬性的 context 對象芹助,因此你可以調用 context.commit 提交一個 mutation,或者通過 context.statecontext.getters 來獲取 state 和 getters闲先。
使用es6可以簡化代碼為:

actions: {
  increment ({ commit }) {
    commit('increment')
  }
}

分發(fā)Action
Action 通過 store.dispatch 方法觸發(fā):

store.dispatch('increment')

我們可以在 action 內部執(zhí)行異步操作状土,也支持同樣的載荷方式和對象方式進行分發(fā):

actions: {
  incrementAsync ({ commit }) {
    setTimeout(() => {
      commit('increment')
    }, 1000)
  }
}

// 以載荷形式分發(fā)
store.dispatch('incrementAsync', {
  amount: 10
})

// 以對象形式分發(fā)
store.dispatch({
  type: 'incrementAsync',
  amount: 10
})

來看一個更加實際的購物車示例,涉及到調用異步 API 和分發(fā)多重 mutation:

actions: {
  checkout ({ commit, state }, products) {
    // 把當前購物車的物品備份起來
    const savedCartItems = [...state.cart.added]
    // 發(fā)出結賬請求伺糠,然后樂觀地清空購物車
    commit(types.CHECKOUT_REQUEST)
    // 購物 API 接受一個成功回調和一個失敗回調
    shop.buyProducts(
      products,
      // 成功操作
      () => commit(types.CHECKOUT_SUCCESS),
      // 失敗操作
      () => commit(types.CHECKOUT_FAILURE, savedCartItems)
    )
  }
}

簡單地來說蒙谓,就相當于我讓朋友幫我去買書,買成功了就跟這個管理員結賬训桶,如果不成功累驮,就去找另一個來解決。那么這個 checkout 就相當于朋友舵揭。

7. Modules

Vuex 允許我們將 store 分割成模塊(module)谤专。每個模塊擁有自己的 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 的狀態(tài)
store.state.b // -> moduleB 的狀態(tài)
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末箱叁,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子惕医,更是在濱河造成了極大的恐慌耕漱,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,681評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件抬伺,死亡現(xiàn)場離奇詭異螟够,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,205評論 3 399
  • 文/潘曉璐 我一進店門妓笙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來若河,“玉大人,你說我怎么就攤上這事寞宫∠舾#” “怎么了?”我有些...
    開封第一講書人閱讀 169,421評論 0 362
  • 文/不壞的土叔 我叫張陵辈赋,是天一觀的道長鲫忍。 經常有香客問我,道長钥屈,這世上最難降的妖魔是什么悟民? 我笑而不...
    開封第一講書人閱讀 60,114評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮篷就,結果婚禮上射亏,老公的妹妹穿的比我還像新娘。我一直安慰自己竭业,他們只是感情好智润,可當我...
    茶點故事閱讀 69,116評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著永品,像睡著了一般做鹰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上鼎姐,一...
    開封第一講書人閱讀 52,713評論 1 312
  • 那天钾麸,我揣著相機與錄音,去河邊找鬼炕桨。 笑死饭尝,一個胖子當著我的面吹牛,可吹牛的內容都是我干的献宫。 我是一名探鬼主播钥平,決...
    沈念sama閱讀 41,170評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼姊途!你這毒婦竟也來了涉瘾?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 40,116評論 0 277
  • 序言:老撾萬榮一對情侶失蹤捷兰,失蹤者是張志新(化名)和其女友劉穎立叛,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體贡茅,經...
    沈念sama閱讀 46,651評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡秘蛇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,714評論 3 342
  • 正文 我和宋清朗相戀三年其做,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片赁还。...
    茶點故事閱讀 40,865評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡妖泄,死狀恐怖,靈堂內的尸體忽然破棺而出艘策,到底是詐尸還是另有隱情蹈胡,我是刑警寧澤,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布柬焕,位于F島的核電站审残,受9級特大地震影響,放射性物質發(fā)生泄漏斑举。R本人自食惡果不足惜搅轿,卻給世界環(huán)境...
    茶點故事閱讀 42,211評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望富玷。 院中可真熱鬧璧坟,春花似錦、人聲如沸赎懦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,699評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽励两。三九已至黎茎,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間当悔,已是汗流浹背傅瞻。 一陣腳步聲響...
    開封第一講書人閱讀 33,814評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留盲憎,地道東北人嗅骄。 一個月前我還...
    沈念sama閱讀 49,299評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像饼疙,于是被迫代替她去往敵國和親溺森。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,870評論 2 361

推薦閱讀更多精彩內容

  • 1.vuex是什么 Vuex 是一個專為 Vue.js 應用程序開發(fā)的狀態(tài)管理模式窑眯。它采用集中式存儲管理應用的所有...
    芒果香蕉蘋果梨閱讀 129評論 0 0
  • 本文為課程 vuex深入淺出 的學習總結與記錄屏积;同時參照了vuex官方文檔。文中demo的代碼可參考:我的碼云 一...
    明滅_閱讀 8,750評論 1 28
  • Vuex是一個專為 Vue.js 應用程序開發(fā)的狀態(tài)管理模式磅甩。它采用集中式存儲管理應用的所有組件的狀態(tài)炊林,并以相應的...
    夢安web開發(fā)閱讀 232評論 0 2
  • Vuex的概述 Vuex是什么 Vuex是實現(xiàn)組件全局狀態(tài)(數(shù)據(jù))管理的一種機制,可以方便的實現(xiàn)組件之間數(shù)據(jù)的共享...
    Tammie_a56e閱讀 306評論 0 1
  • 一更胖、Vuex是什么 Vuex 是一個專為 Vue.js 應用程序開發(fā)的狀態(tài)管理模式。它采用集中式存儲管理應用的所有...
    尋找夢的豬豬閱讀 274評論 0 0