vuex 初始化源码

我们先把vuex安装到vue中

import Vue from 'vue'
import Vuex from 'vuex'
import moduleA from './modules/moduleA'

Vue.use(Vuex)

const debug = process.env.NODE_ENV !== 'production'

const store = new Vuex.Store({
    modules: {
      moduleA,
    },
    strict: debug,
  })

export default  store
import Vue from 'vue'
import App from './App.vue'
import store from './store'

Vue.config.productionTip = false

new Vue({
  store,
  render: h => h(App)
}).$mount("#app")

上面我们可以看到我们在options中加入了store属性
接下来我们看vuex的源码如何工作的?

.vuex安装的源码显示?

.vuex安装后我们可以看到vuex的初始化vuexInit函数运行了3次,都起什么作用?(一次是vue的入口地址显示, 二次是vuex自身源码需要实例化vue)

>目的:主要是为了说明vuex自身源码需要实例化vue 2次,在实际项目中总数会大于3次

一、vuex安装的源码显示?

我们知道Vue.use(Vuex)的源码原理,找到vuex的install函数

function install (_Vue) {
  if (Vue && _Vue === Vue) {
    if ((process.env.NODE_ENV !== 'production')) {
      console.error(
        '[vuex] already installed. Vue.use(Vuex) should be called only once.'
      );
    }
    return
  }
  Vue = _Vue;
  applyMixin(Vue);
}

接着查看 applyMixin(Vue)函数

.我们用的是版本是2.6.11,所以只需要了解version >= 2这个分支即可

这里我们看到会给各个vue实例写入{ beforeCreate: vuexInit }函数

function applyMixin (Vue) {
  var version = Number(Vue.version.split('.')[0]);
  if (version >= 2) {
    Vue.mixin({ beforeCreate: vuexInit });
  } else {
   ......
    };
  }

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

  function vuexInit () {

    var options = this.$options;
    // 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;
    }

  }
}

接着从chrome的调试工具中我们也可以看到,已经写入vue的$options的beforeCreate中.


vuexInit function

vuex安装后我们可以看到vuex的初始化vuexInit函数运行了3次,都起什么作用?

我们已经知道vuexInit写入了vue的$options的beforeCreate,它运行了3次,也就说明有3个vue的实例生成

1.vue的entry的main.js

new Vue({
  store,
  render: h => h(App)
}).$mount("#app")

作用:初始化vue实例并渲染显示到界面

2.在vuex的源码中我们可以看到

var Store = function Store (options) {
  ......
  this._watcherVM = new Vue();
  ......
}

作用:我们可以看到Store.prototype.watch实际上运行的就是Vue原型链上的函数$watch

Store.prototype.watch = function watch (getter, cb, options) {
    var this$1 = this;

  if ((process.env.NODE_ENV !== 'production')) {
    assert(typeof getter === 'function', "store.watch only accepts a function.");
  }
  return this._watcherVM.$watch(function () { return getter(this$1.state, this$1.getters); }, cb, options)
};

3.在vuex的源码中我们可以看到

function resetStoreVM (store, state, hot) {
  var oldVm = store._vm;
  ......
  store._vm = new Vue({
    data: {
      $$state: state
    },
    computed: computed
  });
 ......
  if (oldVm) {
    if (hot) {
      // dispatch changes in all subscribed watchers
      // to force getter re-evaluation for hot reloading.
      store._withCommit(function () {
        oldVm._data.$$state = null;
      });
    }
    Vue.nextTick(function () { return oldVm.$destroy(); });
  }
}

作用:这里我们看到这个vue实例的data对象是为了对比变化实例热更新

你可能感兴趣的:(vuex 初始化源码)