Register Mutation, Action, getters, and submodules

  • Registered Mutation

After receiving the mutations, it will execute module. ForEachMutation, which is the forEachMutation function of the root module instance. The mutation function will determine whether mutations are available on the current structure, and if so, Then executes forEachValue (this) _rawModule) mutations, fn), forEachValue function is through the Object. The keys to traverse the first parameter to the incoming obj, and then put the obj each value as the first parameter of fn, The key of each item is the second argument to the fn function. The first mutation of the callback is the value of the mutation in the module instance that was passed in, and the second key is the corresponding key. NamespacedType = namespacedType = namespacedType = namespacedType = key RegisterMutation (Store, namespacedType, mutation, local) was then performed. The registerMutation function, on its first call, initializes the store._mutations[type] array, and pushes the wrappedMutationHandler function into the array, _mutations[type], then handler.call(store, local.state, payload) will be executed. State as the first parameter, payload as the second parameter. Local. State is handled in the makeLocalContext function. If the local. State called here is the state of module B (assuming module A nested within module B), it will eventually be proxied to state.a.b.xx. Correctly access the state corresponding to the current module. After module.forEachMutation, the Mutation will be complete

// src/store.js
function installModule (store, rootState, path, module, hot) {...module.forEachMutation((mutation, key) = > {
    constnamespacedType = namespace + key registerMutation(store, namespacedType, mutation, 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)
  })
}
// src/module/module.js
export default class Module {... forEachMutation (fn) {if (this._rawModule.mutations) {
      forEachValue(this._rawModule.mutations, fn)
    }
  }
}
// src/util.js
export function forEachValue (obj, fn) {
  Object.keys(obj).forEach(key= > fn(obj[key], key))
}
Copy the code
  • Register the Action

Module. forEachAction = module. ForEachAction = module. ForEachAction = module. ForEachAction returns the action value as the first argument and the key as the second argument. ForEachAction returns the action value as the second argument. Execute the callback to get the type (check if the action value has root and if it does, do not concatenate the namespace), and then get the handler’s specific handler (if the object is passed in, get the handler’s function). We then execute the registerAction function, which, like registerMutation, defines the store._actions[type] as an empty array, and then pushwrappedActionHandler. When executing this function, MIT, getters: local.getters, state: local.state, rootGetters: Store. Getters, rootState: store. State} this is also the first parameter of the action mentioned in the documentation to get the root getter and rootState. Then determine if the action returns a then method (PROMISE), then call promise.resolve (res).

// src/store.js
function installModule (store, rootState, path, module, hot) {...module.forEachAction((action, key) = > {
    const type = action.root ? key : namespace + key
    consthandler = action.handler || action registerAction(store, type, handler, local) }) ... }...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) {
      ...
    } else {
      return res
    }
  })
}
Copy the code
  • Registered Getter

After the action is registered, the module.forEachGetter function is executed, which also concatenates the namespace with the current key, and then the registerGetter function is called. Store. _mutations[type] and store._actions[type] correspond to an array, while store. _wrappedgetter [type] corresponds to a function wrappedGetter, If execution wrappedGetter parameter for the local state, local, getters, store. State, store. Getters (document).

// src/store.js
function installModule (store, rootState, path, module, hot) {...module.forEachGetter((getter, key) = > {
    const namespacedType = namespace + key
    registerGetter(store, namespacedType, getter, local)
  })
  ...
}

function registerGetter (store, type, rawGetter, local) {
  if (store._wrappedGetters[type]) {
    ...
    return
  }
  store._wrappedGetters[type] = function wrappedGetter (store) {
    return rawGetter(
      local.state, // local state
      local.getters, // local getters
      store.state, // root state
      store.getters // root getters)}}Copy the code
  • Registration submodule

ForEachChild is executed to determine if the current module has _children. Then execute installModule(store, rootState, path.concat(key), Child, hot) and execute the passed path parameter to concatenate the key with the current path. That is, when executing the installModule of the submodule, isRoot is false. GetNestedState (this.state, path-.slice (0, -1))); path[path-.length-1]; Set (parentState, moduleName, module.state). ParentState is added with the current module name as key and the current state as value. This is why global access to the state of the submodule can be accessed via state.a.b.xx. This will recursively execute installModules if they are found to have child modules, which will recursively register each module.

// src/store.js
function installModule (store, rootState, path, module, hot) {...if(! isRoot && ! hot) {const parentState = getNestedState(rootState, path.slice(0, -1))
    const moduleName = path[path.length - 1]
    store._withCommit(() = > {
      if (__DEV__) {
        ...
      }
      Vue.set(parentState, moduleName, module.state)
    })
  }
  ...
  module.forEachChild((child, key) = > {
    installModule(store, rootState, path.concat(key), child, hot)
  })
  ...
}
Copy the code