對(duì)vuex原理的理解

使用的源碼版本為3.5.1

定義

Vuex 是一個(gè)專為 Vue.js 應(yīng)用程序開發(fā)的狀態(tài)管理模式蹂楣。它采用集中式存儲(chǔ)管理應(yīng)用的所有組件的狀態(tài)澳化,并以相應(yīng)的規(guī)則保證狀態(tài)以一種可預(yù)測(cè)的方式發(fā)生變化。

使用場(chǎng)景

它的優(yōu)勢(shì)用于解決下面兩個(gè)問題:

  1. 多個(gè)視圖依賴于同一狀態(tài)澈蚌。
  2. 來自不同視圖的行為需要變更同一狀態(tài)莉钙。

解決方式是:

  • 全局單例集中管理
  • 數(shù)據(jù)單向流動(dòng)

源碼架構(gòu)

vuex源碼架構(gòu)核心點(diǎn)兩個(gè):

  • 觀察者模式
  • 把state中的狀態(tài)處理成響應(yīng)式的

觀察者模式

我們定義的Action和Mutation都是具體的事件仇冯,會(huì)被vuex搜集保存起來

function installModule (store, rootState, path, module, hot) {

  module.forEachMutation((mutation, key) => {
    const namespacedType = namespace + key
    registerMutation(store, namespacedType, mutation, local)
  })

  module.forEachAction((action, key) => {
    const type = action.root ? key : namespace + key
    const handler = action.handler || action
    registerAction(store, type, handler, local)
  })
}
function registerMutation (store, type, handler, local) {
  const entry = store._mutations[type] || (store._mutations[type] = [])
  entry.push(function wrappedMutationHandler (payload) {
    handler.call(store, local.state, payload)
  })
}

function registerAction (store, type, handler, local) {
  const entry = store._actions[type] || (store._actions[type] = [])
  entry.push(function wrappedActionHandler (payload) {
    let res = handler.call(store, {
      dispatch: local.dispatch,
      commit: local.commit,
      getters: local.getters,
      state: local.state,
      rootGetters: store.getters,
      rootState: store.state
    }, payload)
    if (!isPromise(res)) {
      res = Promise.resolve(res)
    }
    if (store._devtoolHook) {
      return res.catch(err => {
        store._devtoolHook.emit('vuex:error', err)
        throw err
      })
    } else {
      return res
    }
  })
}

dispatch和commit的作用是發(fā)布事件

 // 只保留核心代碼
  dispatch (_type, _payload) {
    // check object-style dispatch
    const {
      type,
      payload
    } = unifyObjectStyle(_type, _payload)

    const action = { type, payload }
    const entry = this._actions[type]
    const result = entry.length > 1
      ? Promise.all(entry.map(handler => handler(payload)))
      : entry[0](payload)
 // 只保留核心代碼
  commit (_type, _payload, _options) {
    // check object-style commit
    const {
      type,
      payload,
      options
    } = unifyObjectStyle(_type, _payload, _options)

    const mutation = { type, payload }
    const entry = this._mutations[type]

    this._withCommit(() => {
      entry.forEach(function commitIterator (handler) {
        handler(payload)
      })
    })
  }

dispach發(fā)布事件,遍歷找到對(duì)應(yīng)的action處理已烤,處理異步操作完成之后調(diào)用commit提交事件鸠窗,遍歷找到對(duì)應(yīng)的mutation去處理(主要是修改state中數(shù)據(jù)狀態(tài)),這樣就完成了整個(gè)流程

響應(yīng)式原理

在store的構(gòu)造器中會(huì)調(diào)用resetStoreVM

 // 只保留核心代碼
function resetStoreVM (store, state, hot) {
  store._vm = new Vue({
    data: {
      $$state: state
    },
    computed
  })
}

核心是創(chuàng)建一個(gè)vue實(shí)例胯究,利用vue響應(yīng)式原理把state的中的數(shù)據(jù)處理成響應(yīng)式的稍计。
vue響應(yīng)式的原理可以看我的這篇文章:從源碼的角度分析Vue視圖更新和nexttick機(jī)制

參考:
http://www.reibang.com/p/d95a7b8afa06
https://vuex.vuejs.org/zh/guide/actions.html
https://tech.meituan.com/2017/04/27/vuex-code-analysis.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市裕循,隨后出現(xiàn)的幾起案子臣嚣,更是在濱河造成了極大的恐慌,老刑警劉巖剥哑,帶你破解...
    沈念sama閱讀 218,451評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件硅则,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡株婴,警方通過查閱死者的電腦和手機(jī)怎虫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人揪垄,你說我怎么就攤上這事穷吮。” “怎么了饥努?”我有些...
    開封第一講書人閱讀 164,782評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵捡鱼,是天一觀的道長。 經(jīng)常有香客問我酷愧,道長驾诈,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,709評(píng)論 1 294
  • 正文 為了忘掉前任溶浴,我火速辦了婚禮乍迄,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘士败。我一直安慰自己闯两,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評(píng)論 6 392
  • 文/花漫 我一把揭開白布谅将。 她就那樣靜靜地躺著漾狼,像睡著了一般。 火紅的嫁衣襯著肌膚如雪饥臂。 梳的紋絲不亂的頭發(fā)上逊躁,一...
    開封第一講書人閱讀 51,578評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音隅熙,去河邊找鬼稽煤。 笑死,一個(gè)胖子當(dāng)著我的面吹牛囚戚,可吹牛的內(nèi)容都是我干的酵熙。 我是一名探鬼主播,決...
    沈念sama閱讀 40,320評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼弯淘,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼绿店!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起庐橙,我...
    開封第一講書人閱讀 39,241評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤假勿,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后态鳖,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體转培,經(jīng)...
    沈念sama閱讀 45,686評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評(píng)論 3 336
  • 正文 我和宋清朗相戀三年浆竭,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了浸须。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片惨寿。...
    茶點(diǎn)故事閱讀 39,992評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖删窒,靈堂內(nèi)的尸體忽然破棺而出裂垦,到底是詐尸還是另有隱情,我是刑警寧澤肌索,帶...
    沈念sama閱讀 35,715評(píng)論 5 346
  • 正文 年R本政府宣布蕉拢,位于F島的核電站,受9級(jí)特大地震影響诚亚,放射性物質(zhì)發(fā)生泄漏晕换。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評(píng)論 3 330
  • 文/蒙蒙 一站宗、第九天 我趴在偏房一處隱蔽的房頂上張望闸准。 院中可真熱鬧,春花似錦梢灭、人聲如沸夷家。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瘾英。三九已至枣接,卻和暖如春颂暇,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背但惶。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評(píng)論 1 270
  • 我被黑心中介騙來泰國打工耳鸯, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人膀曾。 一個(gè)月前我還...
    沈念sama閱讀 48,173評(píng)論 3 370
  • 正文 我出身青樓县爬,卻偏偏與公主長得像,于是被迫代替她去往敵國和親添谊。 傳聞我的和親對(duì)象是個(gè)殘疾皇子财喳,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評(píng)論 2 355