4

为什么我们在组件中直接this.$store.xx,就可以对vuex进行操作。
每次我们在使用vuex的时候需要

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

Vue.use(Vuex);

Vue.use会执行Vuex对象中的install方法

function install (_Vue) {
    // 防止重复调用install
    if (Vue && _Vue === Vue) {
        console.error('[vuex] already installed.Vue.use(Vuex) should be called only once.');
        return;
    }
    Vue = _Vue;
    applyMixin(Vue);
}

在install方法中调用了applyMixin方法

function applyMixin (Vue) {
    // 获取vue的版本
    var version = Number(Vue.version.split('.')[0]);
    if (version >= 2) {
      Vue.mixin({ beforeCreate: vuexInit });
    } else {
      // 对低于vue低于2的版本处理
      // override init and inject vuex init procedure
      // for 1.x backwards compatibility.
      var _init = Vue.prototype._init;
      Vue.prototype._init = function (options) {
        if ( options === void 0 ) options = {};

        options.init = options.init
          ? [vuexInit].concat(options.init)
          : vuexInit;
        _init.call(this, options);
      };
    }
 }

applyMixin方法中,先获取Vue的版本号,低于2的版本通过重写Vue的原型方法_init来实现目的。对于vue2.x版本,使用全局混入的机制,使用全局混入,它将影响每一个之后创建的 Vue 实例。在实例生命周期beforeCreate的会执行vuexInit方法。

/**
 * Vuex初始化钩子,注入到每个实例的钩子列表中
 * Vuex init hook, injected into each instances init hooks list.
 */
function vuexInit () {
  // 这里的this指向Vue实例
  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;
  }
}
//===============
new Vue({
  router,
  store,    // 在/store/index.js文件中暴露出的:new Vuex.Store出来的对象
  render: h => h(App),
}).$mount('#app');

当我们执行new Vue的时候,其中的参数会被合并到$options中。此时存在options.store,就将实例的$store指向Store实例对象。而在子组件中,$store属性也会指向父组件的$store属性。即在每个实例中this.$store都会指向我们在/store/index.js中new Vuex.Store实例化出来的对象。
以上就是为什么我们再组件中this.$store都能指向Vuex的Store实例对象。


crazyPupil
37 声望4 粉丝

下一篇 »
Vuex commit