vuexのstoreソース機能解析の詳細
4237 ワード
Vuexを使用する場合、通常はStoreクラスをインスタンス化し、定義したactions、getters、mutations、stateなど、オブジェクトが転送されます.storeのコンストラクション関数:
Vuex自体は単一の状態ツリーであり,アプリケーションのすべての状態が大きなオブジェクトに含まれており,我々のアプリケーション規模が増加するにつれて,このStoreは非常に肥大化している.この問題を解決するために、Vuexはstoreをモジュールに分けることができます.各モジュールには、それぞれのstate、mutations、actions、gettersが含まれており、モジュールをネストすることもできます.次にinstallModuleメソッドを見てみましょう.
Vuexではstateへの変更はすべて_withCommit関数パッケージは、stateを同期的に変更する過程でthis.committingの値は常にtrueです.stateの変化を観測するとcommittingの値がtrueでない場合、この状態の修正に問題があることを確認できます.
以上は本文のすべての内容で、みんなの学习に対して役に立つことを望んで、関心を加えて、みんなも多く私を支持することを望みます~
export class Store {
constructor (options = {}) {
// window vue, Vue
if (!Vue && typeof window !== 'undefined' && window.Vue) {
install(window.Vue)
}
if (process.env.NODE_ENV !== 'production') {
// ,
// Vue
assert(Vue, `must call Vue.use(Vuex) before creating a store instance.`)
// Promsie
assert(typeof Promise !== 'undefined', `vuex requires a Promise polyfill in this browser.`)
assert(this instanceof Store, `store must be called with the new operator.`)
}
// , options plugins strict
const {
plugins = [],
strict = false
} = options
//
// , Vuex state mutation , state
this._committing = false
// actions
this._actions = Object.create(null)
this._actionSubscribers = []
// mutatins
this._mutations = Object.create(null)
// getters
this._wrappedGetters = Object.create(null)
// modules
this._modules = new ModuleCollection(options)
this._modulesNamespaceMap = Object.create(null)
// mutation
this._subscribers = []
// Vue , Vue $watch
this._watcherVM = new Vue()
// Store dispatch commit this store
const store = this
const { dispatch, commit } = this
this.dispatch = function boundDispatch (type, payload) {
return dispatch.call(store, type, payload)
}
this.commit = function boundCommit (type, payload, options) {
return commit.call(store, type, payload, options)
}
//
this.strict = strict
const state = this._modules.root.state
// Vuex , ,installModule options ;
// resetStoreVM store._vm, state getters ; 。
installModule(this, state, [], this._modules.root)
resetStoreVM(this, state)
plugins.forEach(plugin => plugin(this))
const useDevtools = options.devtools !== undefined ? options.devtools : Vue.config.devtools
if (useDevtools) {
devtoolPlugin(this)
}
}
Vuex自体は単一の状態ツリーであり,アプリケーションのすべての状態が大きなオブジェクトに含まれており,我々のアプリケーション規模が増加するにつれて,このStoreは非常に肥大化している.この問題を解決するために、Vuexはstoreをモジュールに分けることができます.各モジュールには、それぞれのstate、mutations、actions、gettersが含まれており、モジュールをネストすることもできます.次にinstallModuleメソッドを見てみましょう.
function installModule (store, rootState, path, module, hot) {
// path
const isRoot = !path.length
const namespace = store._modules.getNamespace(path)
// register in namespace map
if (module.namespaced) {
store._modulesNamespaceMap[namespace] = module
}
// ,path , if
// installModule ,
if (!isRoot && !hot) {
const parentState = getNestedState(rootState, path.slice(0, -1))
//
const moduleName = path[path.length - 1]
// state parentState 。
store._withCommit(() => {
Vue.set(parentState, moduleName, module.state)
})
}
const local = module.context = makeLocalContext(store, namespace, path)
// mutations、actions、getters
module.forEachMutation((mutation, key) => {
const namespacedType = namespace + key
registerMutation(store, namespacedType, mutation, local)
})
module.forEachAction((action, key) => {
const type = action.root ? key : namespace + key
const handler = action.handler || action
registerAction(store, type, handler, local)
})
module.forEachGetter((getter, key) => {
const namespacedType = namespace + key
registerGetter(store, namespacedType, getter, local)
})
// modules, installModule
module.forEachChild((child, key) => {
installModule(store, rootState, path.concat(key), child, hot)
})
}
store _withCommit :
_withCommit (fn) {
const committing = this._committing
this._committing = true
fn()
this._committing = committing
}
Vuexではstateへの変更はすべて_withCommit関数パッケージは、stateを同期的に変更する過程でthis.committingの値は常にtrueです.stateの変化を観測するとcommittingの値がtrueでない場合、この状態の修正に問題があることを確認できます.
以上は本文のすべての内容で、みんなの学习に対して役に立つことを望んで、関心を加えて、みんなも多く私を支持することを望みます~