对vuex原理的理解

使用的源码版本为3.5.1

定义

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

使用场景

它的优势用于解决下面两个问题:

  1. 多个视图依赖于同一状态。
  2. 来自不同视图的行为需要变更同一状态。

解决方式是:

  • 全局单例集中管理
  • 数据单向流动

源码架构

vuex源码架构核心点两个:

  • 观察者模式
  • 把state中的状态处理成响应式的

观察者模式

我们定义的Action和Mutation都是具体的事件,会被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的作用是发布事件

 // 只保留核心代码
  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发布事件,遍历找到对应的action处理,处理异步操作完成之后调用commit提交事件,遍历找到对应的mutation去处理(主要是修改state中数据状态),这样就完成了整个流程

响应式原理

在store的构造器中会调用resetStoreVM

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

核心是创建一个vue实例,利用vue响应式原理把state的中的数据处理成响应式的。
vue响应式的原理可以看我的这篇文章:从源码的角度分析Vue视图更新和nexttick机制

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。