Learning record of vuex source code

Time:2020-3-29

First look at the source directory of vuex

Learning record of vuex source code

Source code is insrcUnder directory, the entry file isindex.js(orindex.esm.jsWhen usedimport Vuex from 'vuex'IntroducevuexThe entrance isindex.esm.js(ESM: ES6 module), look inside

import { Store, install } from './store'
import { mapState, mapMutations, mapGetters, mapActions, createNamespacedHelpers } from './helpers'

export default {
  Store,
  install,
  version: '__VERSION__',
  mapState,
  mapMutations,
  mapGetters,
  mapActions,
  createNamespacedHelpers
}

export {
  Store,
  install,
  mapState,
  mapMutations,
  mapGetters,
  mapActions,
  createNamespacedHelpers
}

The first is to introduceStoreandinstallLet’s take a look first.installMethod

export function install (_Vue) {
  //Vue already exists and is equal, which means that vuex has been installed
  if (Vue && _Vue === Vue) {
    //Error is reported in non production environment. Vuex has been installed and the code continues to execute
    if (process.env.NODE_ENV !== 'production') {
      console.error(
        '[vuex] already installed. Vue.use(Vuex) should be called only once.'
      )
    }
    return
  }
  Vue = _Vue
  applyMixin(Vue)
}

The logic of the above code is very simple, executeVuex.installIntroduction of timeVueConstructor, execute lastapplyMixin(Vue)

But, usually, we introduceVuexAfter that, it’s all executionVue.use(vuex)

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

Have a lookvueSource code

// src/core/global-api/use.js
/* @flow */
import { toArray } from '../util/index'
export function initUse (Vue: GlobalAPI) {
  Vue.use = function (plugin: Function | Object) {
    const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
    if (installedPlugins.indexOf(plugin) > -1) {
      return this
    }

    // additional parameters
    const args = toArray(arguments, 1)
    args.unshift(this)
    if (typeof plugin.install === 'function') {
      plugin.install.apply(plugin, args)
    } else if (typeof plugin === 'function') {
      plugin.apply(null, args)
    }
    installedPlugins.push(plugin)
    return this
  }
}

If it comes inpluginYesinstallMethod, executeinstallMethod, of course, we can also attack directlyinstallMethod, the effect is the same

import Vue from 'vue'
import Vuex from 'vuex'

Vuex.install(Vue)

Look again.applyMixinMethod, this method is inmixin.jsin

// vuex/src/minx.js
export default function (Vue) {
  const version = Number(Vue.version.split('.')[0]) // 2

  if (version >= 2) {
    //A beforecreate hook function is mixed into the global
    Vue.mixin({ beforeCreate: vuexInit })
  } else {
    // override init and inject vuex init procedure
    // for 1.x backwards compatibility.
    const _init = Vue.prototype._init
    Vue.prototype._init = function (options = {}) {
      options.init = options.init
        ? [vuexInit].concat(options.init)
        : vuexInit
      _init.call(this, options)
    }
  }

  /**
   * Vuex init hook, injected into each instances init hooks list.
   */

  function vuexInit () {
    const options = this.$options
    //Store injection
    //Make each Vue instance have the $store object (store instance, which contains a series of methods and properties), and it is the same object.
    //First, judge options.store, that's it
    // store injection
    if (options.store) {
      this.$store = typeof options.store === 'function'
        ? options.store()
        : options.store
    } else if (options.parent && options.parent.$store) {
      this.$store = options.parent.$store
    }
  }
}

Have a lookVueIn the source codeVue.mixinMethod

// src/core/global-api/mixin.js
/* @flow */
import { mergeOptions } from '../util/index'
export function initMixin (Vue: GlobalAPI) {
  Vue.mixin = function (mixin: Object) {
    this.options = mergeOptions(this.options, mixin)
    return this
  }
}

In fact, a beforecreate hook function is mixed in the whole world to print the Vue instance

Learning record of vuex source code