Learning record of vuex source code

First look vuex Source directory

The source code is all in the src directory, and the entry file is index.js (or index. ESM. JS). When importing vuex from 'vuex', the entry is index.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 step is to introduce the Store and install. First, look at the install method

export function install (_Vue) {
  // Vue already exists and is equal, which means that Vuex has been install ed
  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 above code logic is very simple. When executing Vuex.install, the Vue constructor is passed in, and then applyMixin(Vue) is executed

However, after we introduce Vuex, we usually execute Vue.use(vuex)

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

Vue.use(Vuex)

Take a look at the vue source 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 the plugin passed in has the install method, execute the install method. Of course, we can also directly hit the direct install method. The effect is the same

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

Vuex.install(Vue)

Take a look at the applyMixin method, which is in mixin.js

// 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
    }
  }
}

Take a look at the Vue.mixin method in Vue's source code

// 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

Keywords: Javascript Vue

Added by stanleycwb on Mon, 25 Nov 2019 16:07:47 +0200