Vuex

packaging

// package.json
{
  name:'vuex'.main:'dist/vuex.common.js'.module:'dist/vuex.esm.js'. }// rollup.main.config.js
export default createEntries([
  ...
  {input:'src/index.js'.file:'dist/vuex.esm.js'.format:'es'.env:'development'},... {input:'src/index.cjs.js'.file:'dist/vuex.common.js'.format:'cjs'.ebv:'development'}])Copy the code

vuex

import { Store, install } from './store'
import { mapState, mapMutations, mapGetters, mapActions, createNamespaceHelpers } from './helpers'
import createLogger from './plugins/logger'

export default{
  Store,
  install,
  version:'__VERSION__',
  mapState,
  mapMutations,
  mapGetters,
  mapActions,
  createNamespaceHelpers,
  createLogger
}
Copy the code

Store

// Determine whether to introduce Vue
let Vue
class Store{
  constructor(options = {}){
    // Check that the current Vue does not exist and is in the browser,Vue has been mounted, assign a value to Vue variable
    if(! Vue &&typeof window! = ='undefined' && window.Vue){
      install(window.Vue)
    }
    const { plugins = [], strict = false } = options 
    // Assign a private variable
    this._commiting = false
    this._actions = Object.create(null)
    this._actionSubscribers = []
    this._mutations = Object.create(null)
    this._wrappedGetters = Object.create(null)
    this._modules = new ModuleCollection(options)
    this._modulesNamespaceMap = Object.create(null)
    this._subscribers = []
    this._watcherVM = new Vue()
    this._makeLocalGettersCache = Object.create(null)
    // Point the context of dispatch and commit to the binding
    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
    // Bind global action/getter/mutationss
    installModule(this,state,[],this._modules.root)
    // Initialize the vm object bound to store
    resetStoreVM(this,state)
    / / the plugin application
    plugins.forEach(plugin= > plugin(this))
    constuseDevtools = options.devtools ! = =undefined ? options.devtools : Vue.config.devtools
    if(useDevtools){
      devtoolPlugin(this)}}get state() {return this._vm._data.$$state
  }
  set state(v) {if(__DEV__){
      asset(false.`use store.replaceState() to explicit replace store state`)}}commit(_type,_payload,_options){
    // Format fetch type,payload,options
    const { type, payload, options} = unifyObjectStyle(_type,_payload,_options)
    const mutation = { type, payload }
    // Get the synchronization event
    const entry = this._mutations[type]
    if(! entry){if(__DEV__){
        console.error(`[vuex] unkonwn mutation type:${type}`)}return
    }
    // Execute synchronous event logic
    this._withCommit(() = > {
      entry.forEach(function commitIterator(handler){
        handler(payload)
      })
    })
    this._subscribers.slice().forEach(sub= > sub(mutation,this.state))
    if(__DEV__ && options && options.slient){
      console.warn(`[vuex] mutation type: ${type}. Slient option has been removed. use the filter funtionality in the vue-devtools`)}}dispatch(_type,_payload){
    / / get the type/paylod
    const { type, payload }= unifyObjectStyle(_type,_payload)
    const action = { type, payload }
    const entry = this.actions[type]
    if(! entry){if(__DEV__){
        console.error(`[vuex] unkonwn action type:${type}`)}return
    }
    // Perform the plug-in's before operation
    try{
      this._actionSubscribers.slice().filter(sub= > sub.before).forEach(sub= > sub.before(action,this.state))
    }catch(e){
      ...
    }
    // Get execution results based on events at Dispatch
    const result = entry.length > 1 ? Promise.all(entry.map(handler= > handler(payload))) : entry[0].payload
    return new Promise((resolve,reject) = > {
      result.then(res= > {
        / / execution plugin. After
        try{
          this._actionSubscribers.slice().filter(sub= > sub.after).forEach(sub= > sub.afetr(action,this.state))
        }catch(e){
          ...
        }
        resolve(res)
      })
    },error= > {
      // plugin.error
      try{
        this._actionSubscribers.slice().filter(sub= > sub.error).forEach(sub= >sub.error(action,this.state,error))
      }catch(e){
        ...
      }
      reject(error)
    })
  }
  subscribe(fn,options){
    // Subscribe to the commit event and return a function to clear the event
    return genericSubscribe(fn,this._subscribers,options)
  }
  subscribeAction(fn,options){
    // Subscribe to the action event and return a function to clear the event
    const subs = typeof fn === 'function' ? { before: fn} : fn
    return genericSubscribe(fn,this._actionSubscribers,options)
  }
  watch(getter,cb,options){
    if(__DEV__){
      asset(typeof getter === 'function'.`store.watch only accepts a function`)}// Responsive listening
    return this._watcherVM.$watch(() = > getter(this.state,this.getters),cb,options)
  }
  replaceState(state){
    / / replace state
    this._withCommit(() = > {
      this._vm._data.$$state = state
    })
  }
  registerModule(path,rawModule,options = {}){
    if(typeof path === 'string') path = [path]
    if(__DEV__){
      assert(Array.isArray(path),`module path must be a string or a Array`)
      assert(path.length > 0.`cannot register the root module by using registerModule`)}// Dynamic registration module
    this._modules.register(path,rawModule)
    // Dynamically register module events/methods /state
    installModule(this.this.state,path,this._module.get(path),options.prevState)
    resetStoreVM(this.this.state)
  }
  unregisterModule(path){
    if(typeof path === 'string') path = [path]
    if(__DEV__){
      asset(Array.isArray(path),`module path must be a string or a array`)}// Unmount the module
    this._modules.unregister(path)
    / / remove state
    this._withCommit(() = > {
      const parentState = getNestedState(this.state,path.slice(0, -1))
      Vue.delete(parentState,path[path.length - 1])
    })
    resetStore(this)}hasModule(path){
    if(typeof path === 'string') path = [path]
    if(__DEV__){
      asset(Array.isArray(path),`module path must be a string or a array`)}// Check whether the module is registered
    return this._modules.isRegistered(path)
  }
  hotUpdate(newOptions){
    // Hot replace updates module/actions
    this._modules.update(newOptions)
    // Update the root node status
    resetStore(this)}_withCommit(fn){
    // Update the status and execute the event
    const commiting = this._committing
    this._committing = true
    fn()
    this._committing = committing
  }
}
Copy the code