Vuex源碼閱讀(二) store內的getters實現邏輯


1. 准備工作

1) 創建一個store,state只包含一個count成員:

new Vuex.Store({
	state: {
		count: 0
	},
	mutations: {
		increment(state) {
			state.count++;
		}
	},
	actions: {
		incrementOfActive: ({ commit }) => {
			commit('increment');
		}
	},
	getters: {
		countOfGetter: (state) => {
			return state.count;
		}
	}
});

  

2) 創建一個Vue對象,並設置store

window.DEMO_VM = new Vue({
	el: '#app',
	store
});

 

2. Vuex對getter做了哪些處理

通過閱讀Vuex的源碼,發現對getter做了下面處理

2.1 進行局部化

說明:當創建Vuex.Store時,如果內部嵌套了多個stroe(Module),將進行局部化,目的是為了Module各自的getters都保持對各自state的訪問。

代碼

function registerGetter(store, type, rawGetter, local) {
	if (store._wrappedGetters[type]) {
		if (__DEV__) {
			console.error(`[vuex] duplicate getter key: ${type}`);
		}
		return;
	}
	store._wrappedGetters[type] = function wrappedGetter(store) {
		return rawGetter(
			local.state, // local state
			local.getters, // local getters
			store.state, // root state
			store.getters // root getters
		);
	};
}

 

2.2 注冊為計算屬性

說明:初始化內部變量_vm,將getter注冊為_vm的計算屬性。

// 獲取getters內的每個getter封裝到_vm
const wrappedGetters = store._wrappedGetters;
const computed = {};
forEachValue(wrappedGetters, (fn, key) => {
    computed[key] = partial(fn, store);
	Object.defineProperty(store.getters, key, {
		get: () => {
			return store._vm[key];
		},
		enumerable: true // for local getters
	});
});

store._vm = new Vue({
	data: {
		$$state: state
	},
	computed
});

 

3. 解析邏輯

3.1 $store.getters.countOfGetter值從哪里來

說明:雖然我們創建的countOfGetter的內部為"return state.count;",難道我們每次調用countOfGetter都是執行了對應的函數嗎?

從2.2節的源碼上看,Vuex對countOfGetter設置了get特性,每次調用都是從_vm.countOfGetter獲取。

所以當調用 window.DEMO_VM.$store.getters.countOfGetter 時 → 實際上從返回為 window.DEMO_VM.$store._vm.countOfGetter

這里要注意一點store.getters都被注冊為了_vm的計算屬性。

官方對計算屬性好處介紹:“計算屬性是基於它們的響應式依賴進行緩存的。只在相關響應式依賴發生改變時它們才會重新求值。

總結:這樣子也進一步說明store.getters保留了緩存特性。

 

3.2 修改了state,getters為什么會變更

說明:跟上面的說的getters注冊為計算屬性一樣,_vm綁定了state與getters對應的關系,當變更state時,對應的getter也會發生改變。

 

4. 問題

4.1 為何不直接在組件外修改state?

既然可以通過"window.DEMO_VM.$store.state.count = 4" 這樣操作來修改state,為什么還需要mutations、actions?

有下面幾個原因:

1) 統一規范。如果都像這樣在外部直接修改state,那么整個Vuex體系就會亂掉,直接當成了全局變量(緩存)來使用了。

2) hooks:mutations、actions內部的調用了都附加了Subscribe的處理。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM