vuexのstoreソース機能解析の詳細

4237 ワード

Vuexを使用する場合、通常はStoreクラスをインスタンス化し、定義したactions、getters、mutations、stateなど、オブジェクトが転送されます.storeのコンストラクション関数:
export class Store {
 constructor (options = {}) {
  //  window    vue,     Vue
  if (!Vue && typeof window !== 'undefined' && window.Vue) {
   install(window.Vue)
  }
 
  if (process.env.NODE_ENV !== 'production') {
   //     ,           
   //    Vue    
   assert(Vue, `must call Vue.use(Vuex) before creating a store instance.`)
   //    Promsie     
   assert(typeof Promise !== 'undefined', `vuex requires a Promise polyfill in this browser.`)
   assert(this instanceof Store, `store must be called with the new operator.`)
  }
 
  //     ,  options  plugins strict
  const {
   plugins = [],
   strict = false
  } = options
 
  //       
  //         ,       Vuex   state        mutation       ,           state
  this._committing = false
  //             actions
  this._actions = Object.create(null)
  this._actionSubscribers = []
  //            mutatins
  this._mutations = Object.create(null)
  //            getters 
  this._wrappedGetters = Object.create(null)
  //             modules
  this._modules = new ModuleCollection(options)
  this._modulesNamespaceMap = Object.create(null)
  //         mutation       
  this._subscribers = []
  //    Vue     ,      Vue      $watch       
  this._watcherVM = new Vue()
 
  //  Store  dispatch commit    this      store    
  const store = this
  const { dispatch, commit } = this
  this.dispatch = function boundDispatch (type, payload) {
   return dispatch.call(store, type, payload)
  }
  this.commit = function boundCommit (type, payload, options) {
   return commit.call(store, type, payload, options)
  }
 
  //         
  this.strict = strict
 
  const state = this._modules.root.state
 
  // Vuex       ,  ,installModule        options              ;
  // resetStoreVM        store._vm,   state   getters    ;          。
  installModule(this, state, [], this._modules.root)
 
  resetStoreVM(this, state)
  plugins.forEach(plugin => plugin(this))
 
  const useDevtools = options.devtools !== undefined ? options.devtools : Vue.config.devtools
  if (useDevtools) {
   devtoolPlugin(this)
  }
 }


Vuex自体は単一の状態ツリーであり,アプリケーションのすべての状態が大きなオブジェクトに含まれており,我々のアプリケーション規模が増加するにつれて,このStoreは非常に肥大化している.この問題を解決するために、Vuexはstoreをモジュールに分けることができます.各モジュールには、それぞれのstate、mutations、actions、gettersが含まれており、モジュールをネストすることもできます.次にinstallModuleメソッドを見てみましょう.
function installModule (store, rootState, path, module, hot) {
 //   path           
 const isRoot = !path.length
 const namespace = store._modules.getNamespace(path)
 
 // register in namespace map
 if (module.namespaced) {
  store._modulesNamespaceMap[namespace] = module
 }
 
 //       ,path  ,   if
 //     installModule      ,       
 if (!isRoot && !hot) {
  const parentState = getNestedState(rootState, path.slice(0, -1))
  //    
  const moduleName = path[path.length - 1]
  //       state   parentState 。      
  store._withCommit(() => {
   Vue.set(parentState, moduleName, module.state)
  })
 }
 
 const local = module.context = makeLocalContext(store, namespace, path)
 
 //  mutations、actions、getters    
 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)
 })
 
 module.forEachGetter((getter, key) => {
  const namespacedType = namespace + key
  registerGetter(store, namespacedType, getter, local)
 })
 
 //   modules,    installModule     
 module.forEachChild((child, key) => {
  installModule(store, rootState, path.concat(key), child, hot)
 })
}
store _withCommit        :
 
 _withCommit (fn) {
  const committing = this._committing
  this._committing = true
  fn()
  this._committing = committing
 }

Vuexではstateへの変更はすべて_withCommit関数パッケージは、stateを同期的に変更する過程でthis.committingの値は常にtrueです.stateの変化を観測するとcommittingの値がtrueでない場合、この状態の修正に問題があることを確認できます.
以上は本文のすべての内容で、みんなの学习に対して役に立つことを望んで、関心を加えて、みんなも多く私を支持することを望みます~