Vuex
2020-10-20 10:01:14 0 举报
AI智能生成
源码Vuex
作者其他创作
大纲/内容
Store
constructor (options = {})
this._modules = new ModuleCollection(options)
ModuleCollection
constructor (rawRootModule)
this.register([], rawRootModule, false)
get (path)
return path.reduce((module, key) => {
return module.getChild(key)
}, this.root)
return module.getChild(key)
}, this.root)
getNamespace (path)
let module = this.root
return path.reduce((namespace, key) => {
module = module.getChild(key)
return namespace + (module.namespaced ? key + '/' : '')
}, '')
return path.reduce((namespace, key) => {
module = module.getChild(key)
return namespace + (module.namespaced ? key + '/' : '')
}, '')
update (rawRootModule)
update (rawRootModule) {
update([], this.root, rawRootModule)
}
update([], this.root, rawRootModule)
}
targetModule.update(newModule)
调用module.js中的update方法
if (newModule.modules),存在子模块,递归调用
register (path, rawModule, runtime = true)
const newModule = new Module(rawModule, runtime)
Module
constructor (rawModule, runtime)
get namespaced ()
return !!this._rawModule.namespaced
addChild (key, module)
this._children[key] = module
removeChild (key)
delete this._children[key]
getChild (key)
return this._children[key]
update (rawModule)
forEachChild (fn)
forEachChild (fn) {
forEachValue(this._children, fn)
}
forEachValue(this._children, fn)
}
forEachGetter (fn)
if (this._rawModule.getters) {
forEachValue(this._rawModule.getters, fn)
}
forEachValue(this._rawModule.getters, fn)
}
forEachAction (fn)
if (this._rawModule.actions) {
forEachValue(this._rawModule.actions, fn)
}
forEachValue(this._rawModule.actions, fn)
}
forEachMutation (fn)
if (this._rawModule.mutations) {
forEachValue(this._rawModule.mutations, fn)
}
forEachValue(this._rawModule.mutations, fn)
}
if (path.length === 0) {
this.root = newModule
} else {
const parent = this.get(path.slice(0, -1))
parent.addChild(path[path.length - 1], newModule)
}
this.root = newModule
} else {
const parent = this.get(path.slice(0, -1))
parent.addChild(path[path.length - 1], newModule)
}
register nested modules
if (rawModule.modules) {
forEachValue(rawModule.modules, (rawChildModule, key) => {
this.register(path.concat(key), rawChildModule, runtime)
})
}
forEachValue(rawModule.modules, (rawChildModule, key) => {
this.register(path.concat(key), rawChildModule, runtime)
})
}
unregister (path)
const parent = this.get(path.slice(0, -1))
const key = path[path.length - 1]
只可注销register的,不可注销构造函数创造的
if (!parent.getChild(key).runtime) return
parent.removeChild(key)
const { dispatch, commit } = this
this.dispatch = function boundDispatch (type, payload) {
return dispatch.call(store, type, payload)
}
return dispatch.call(store, type, payload)
}
this.commit = function boundCommit (type, payload, options) {
return commit.call(store, type, payload, options)
}
return commit.call(store, type, payload, options)
}
const state = this._modules.root.state
installModule (this, state, [], this._modules.root)
const namespace = store._modules.getNamespace(path)
if (module.namespaced)
store._modulesNamespaceMap[namespace] = module
set state
获取上下文
const local = module.context = makeLocalContext(store, namespace, path)
function makeLocalContext (store, namespace, path)
const noNamespace = namespace === ''
const local = {
dispatch,
commit
}
dispatch,
commit
}
dispatch
noNamespace ?
是
store.dispatch
否
(_type, _payload, _options) => {
const args = unifyObjectStyle(_type, _payload, _options)
const { payload, options } = args
let { type } = args
if (!options || !options.root) {
type = namespace + type
}
return store.dispatch(type, payload)
}
const args = unifyObjectStyle(_type, _payload, _options)
const { payload, options } = args
let { type } = args
if (!options || !options.root) {
type = namespace + type
}
return store.dispatch(type, payload)
}
commit
noNamespace ?
是
store.commit
否
(_type, _payload, _options) => {
const args = unifyObjectStyle(_type, _payload, _options)
const { payload, options } = args
let { type } = args
if (!options || !options.root) {
type = namespace + type
}
store.commit(type, payload, options)
}
const args = unifyObjectStyle(_type, _payload, _options)
const { payload, options } = args
let { type } = args
if (!options || !options.root) {
type = namespace + type
}
store.commit(type, payload, options)
}
Object.defineProperties local
getters
getters: {
get: noNamespace
? () => store.getters
: () => makeLocalGetters(store, namespace)
}
get: noNamespace
? () => store.getters
: () => makeLocalGetters(store, namespace)
}
function makeLocalGetters (store, namespace)
判断缓存if (!store._makeLocalGettersCache[namespace])
const gettersProxy = {}
const splitPos = namespace.length
Object.keys(store.getters).forEach(type => {})
const localType = type.slice(splitPos)
Object.defineProperty(gettersProxy, localType, {
get: () => store.getters[type],
enumerable: true
})
get: () => store.getters[type],
enumerable: true
})
store._makeLocalGettersCache[namespace] = gettersProxy
return store._makeLocalGettersCache[namespace]
state
state: {
get: () => getNestedState(store.state, path)
}
get: () => getNestedState(store.state, path)
}
function getNestedState (state, path)
return path.reduce((state, key) => state[key], state)
return local
注册mutations
module.forEachMutation((mutation, key) => {
const namespacedType = namespace + key
registerMutation(store, namespacedType, mutation, local)
})
const namespacedType = namespace + key
registerMutation(store, namespacedType, mutation, local)
})
function registerMutation (store, type, handler, local)
const entry = store._mutations[type] || (store._mutations[type] = [])
entry.push
function wrappedMutationHandler (payload) {
handler.call(store, local.state, payload)
})
handler.call(store, local.state, payload)
})
注册actions
module.forEachAction((action, key) => {
const type = action.root ? key : namespace + key
const handler = action.handler || action
registerAction(store, type, handler, local)
})
const type = action.root ? key : namespace + key
const handler = action.handler || action
registerAction(store, type, handler, local)
})
function registerAction (store, type, handler, local)
const entry = store._actions[type] || (store._actions[type] = [])
entry.push
function wrappedActionHandler (payload)
let res = handler.call(store, {
dispatch: local.dispatch,
commit: local.commit,
getters: local.getters,
state: local.state,
rootGetters: store.getters,
rootState: store.state
}, payload)
dispatch: local.dispatch,
commit: local.commit,
getters: local.getters,
state: local.state,
rootGetters: store.getters,
rootState: store.state
}, payload)
if (!isPromise(res)) {
res = Promise.resolve(res)
}
res = Promise.resolve(res)
}
return res
注册getters
module.forEachGetter((getter, key) => {
const namespacedType = namespace + key
registerGetter(store, namespacedType, getter, local)
})
const namespacedType = namespace + key
registerGetter(store, namespacedType, getter, local)
})
function registerGetter (store, type, rawGetter, local)
store._wrappedGetters[type] = function wrappedGetter (store) {
return rawGetter(
local.state, // local state
local.getters, // local getters
store.state, // root state
store.getters // root getters
)
}
return rawGetter(
local.state, // local state
local.getters, // local getters
store.state, // root state
store.getters // root getters
)
}
遍历子模块,递归安装
module.forEachChild((child, key) => {
installModule(store, rootState, path.concat(key), child, hot)
})
installModule(store, rootState, path.concat(key), child, hot)
})
resetStoreVM (this, state)
function resetStoreVM (store, state, hot)
const oldVm = store._vm
// bind store public getters
store.getters = {}
// reset local getters cache
store._makeLocalGettersCache = Object.create(null)
const wrappedGetters = store._wrappedGetters
const computed = {}
// bind store public getters
store.getters = {}
// reset local getters cache
store._makeLocalGettersCache = Object.create(null)
const wrappedGetters = store._wrappedGetters
const computed = {}
forEachValue wrappedGetters
computed[key] = partial(fn, store)
Object.defineProperty(store.getters, key, {
get: () => store._vm[key],
enumerable: true // for local getters
})
get: () => store._vm[key],
enumerable: true // for local getters
})
store._vm = new Vue({
data: {
$$state: state
},
computed
})
data: {
$$state: state
},
computed
})
enableStrictMode (store)
if oldVm
if hot
store._withCommit(() => {
oldVm._data.$$state = null
})
oldVm._data.$$state = null
})
Vue.nextTick(() => oldVm.$destroy())
plugins.forEach(plugin => plugin(this))
get state ()
return this._vm._data.$$state
commit (_type, _payload, _options)
unifyObjectStyle
const entry = this._mutations[type]
this._withCommit(() => {
entry.forEach(function commitIterator (handler) {
handler(payload)
})
})
entry.forEach(function commitIterator (handler) {
handler(payload)
})
})
this._subscribers
.slice()
.forEach(sub => sub(mutation, this.state))
.slice()
.forEach(sub => sub(mutation, this.state))
dispatch (_type, _payload)
unifyObjectStyle
const entry = this._actions[type]
this._actionSubscribers中before函数的执行
const result = entry.length > 1
? Promise.all(entry.map(handler => handler(payload)))
: entry[0](payload)
? Promise.all(entry.map(handler => handler(payload)))
: entry[0](payload)
result.then中执行this._actionSubscribers中的after函数
subscribe (fn)
subscribe (fn) {
return genericSubscribe(fn, this._subscribers)
}
return genericSubscribe(fn, this._subscribers)
}
genericSubscribe
subscribeAction (fn)
subscribeAction (fn) {
const subs = typeof fn === 'function' ? { before: fn } : fn
return genericSubscribe(subs, this._actionSubscribers)
}
const subs = typeof fn === 'function' ? { before: fn } : fn
return genericSubscribe(subs, this._actionSubscribers)
}
watch (getter, cb, options)
return this._watcherVM.$watch(() => getter(this.state, this.getters), cb, options)
replaceState (state)
replaceState (state) {
this._withCommit(() => {
this._vm._data.$$state = state
})
}
this._withCommit(() => {
this._vm._data.$$state = state
})
}
registerModule (path, rawModule, options = {})
if (typeof path === 'string') path = [path]
this._modules.register(path, rawModule)
installModule(this, this.state, path, this._modules.get(path), options.preserveState)
resetStoreVM(this, this.state)
unregisterModule (path)
if (typeof path === 'string') path = [path]
this._modules.unregister(path)
this._withCommit(() => {
const parentState = getNestedState(this.state, path.slice(0, -1))
Vue.delete(parentState, path[path.length - 1])
})
const parentState = getNestedState(this.state, path.slice(0, -1))
Vue.delete(parentState, path[path.length - 1])
})
resetStore(this)
function resetStore (store, hot)
installModule(store, state, [], store._modules.root, true)
resetStoreVM(store, state, hot)
hotUpdate
hotUpdate (newOptions) {
this._modules.update(newOptions)
resetStore(this, true)
}
this._modules.update(newOptions)
resetStore(this, true)
}
resetStore(this, true)
install
applyMixin(vue)
Vue.mixin({ beforeCreate: vuexInit })
options.store
this.$store = options.store
options.parent && options.parent.$store
this.$store = options.parent.$store
mapState
normalizeNamespace
normalizeMap
res[key] = function mappedState
return typeof val === 'function'
? val.call(this, state, getters)
: state[val]
? val.call(this, state, getters)
: state[val]
mapMutations
normalizeNamespace
normalizeMap
res[key] = function mappedMutation (...args)
return typeof val === 'function'
? val.apply(this, [commit].concat(args))
: commit.apply(this.$store, [val].concat(args))
? val.apply(this, [commit].concat(args))
: commit.apply(this.$store, [val].concat(args))
mapGetters
normalizeNamespace
normalizeMap
res[key] = function mappedGetter
val = namespace + val
return this.$store.getters[val]
mapActions
normalizeNamespace
normalizeMap
res[key] = function mappedAction (...args)
return typeof val === 'function'
? val.apply(this, [dispatch].concat(args))
: dispatch.apply(this.$store, [val].concat(args))
? val.apply(this, [dispatch].concat(args))
: dispatch.apply(this.$store, [val].concat(args))
createNameSpacedHelpers
export const createNamespacedHelpers = (namespace) => ({
mapState: mapState.bind(null, namespace),
mapGetters: mapGetters.bind(null, namespace),
mapMutations: mapMutations.bind(null, namespace),
mapActions: mapActions.bind(null, namespace)
})
mapState: mapState.bind(null, namespace),
mapGetters: mapGetters.bind(null, namespace),
mapMutations: mapMutations.bind(null, namespace),
mapActions: mapActions.bind(null, namespace)
})
0 条评论
下一页