vuex 設計思路和實現

API概念的東西就不介紹了, 如果還不瞭解vuex 的應用, 可以去查看官方vuex文檔 。下面着重講解 vuex的原理以及實現

vuex 設計思路

vuex是使用插件機制開發的, vuex 中的 store 本質就是沒有template的隱藏着的vue實例

beforeCreate 混入vuexInit ,vuexInit方法實現了store注入vue組件實例,並註冊了vuex store的引用屬性·$store
在這裏插入圖片描述
vuex 設計思路源碼

  // vuex插件公開的install方法
  function install (_Vue) {
    if (Vue && _Vue === Vue) {
      {
        console.error(
          '[vuex] already installed. Vue.use(Vuex) should be called only once.'
        );
      }
      return
    }
    Vue = _Vue;
    applyMixin(Vue);
  }
  /* ...  */
   var index_cjs = {
    Store: Store,
    install: install, // 開放出去install方法, 直接在項目中使用這個插件
    version: '3.4.0',
    mapState: mapState,
    mapMutations: mapMutations,
    mapGetters: mapGetters,
    mapActions: mapActions,
    createNamespacedHelpers: createNamespacedHelpers
  };

  return index_cjs;
// 混入到項目中
function applyMixin (Vue) {
   var version = Number(Vue.version.split('.')[0]);

   if (version >= 2) {
     Vue.mixin({ beforeCreate: vuexInit }); // 在生命週期beforeCreate創建全局混入函數
   } else {
     // 覆蓋初始化並注入vuex初始化過程
	// 1.x 以上版本兼容。
     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);
     };
   }

   function vuexInit () { // Vuex 初始化鉤子,注入到每個實例初始化鉤子列表中
	   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;
	   }
	}
}


// 使用Vue實例來存儲狀態樹
// 隱藏警告,以防用戶添加了, 一些優先的 global mixins
function resetStoreVM (store, state, hot) {
  /* other... */
  var silent = Vue.config.silent;
  Vue.config.silent = true;
  store._vm = new Vue({ // 創建一個vue 實例
    data: {
      $$state: state
    },
    computed: computed
  });
  Vue.config.silent = silent;
/* other... */
}

vue 響應式設計,依賴監聽、依賴收集

想深刻理解 vuex 的設計思路。要明白 vue 對象數據 Object.defineProperty ,getter/setter 方法的代理劫持的原理

// src/core/instance/state.js
// 初始化組件的state
export function initState (vm: Component) {
  vm._watchers = []
  const opts = vm.$options
  if (opts.props) initProps(vm, opts.props)
  if (opts.methods) initMethods(vm, opts.methods)
  // 當組件存在data屬性
  if (opts.data) {
    initData(vm)
  } else {
    observe(vm._data = {}, true /* asRootData */)
  }
  // 當組件存在 computed屬性
  if (opts.computed) initComputed(vm, opts.computed)
  if (opts.watch && opts.watch !== nativeWatch) {
    initWatch(vm, opts.watch)
  }
}

vuex 就是實現了帶有計算屬性的 data 數據, 原理和 initComputedinitData 是一致的

如果上面已經完全理解,想更深度瞭解響應式依賴 繼續閱讀vue的computed、vm.$data原理

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章