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 數據, 原理和 initComputed
、 initData
是一致的
如果上面已經完全理解,想更深度瞭解響應式依賴 繼續閱讀vue的computed、vm.$data原理