接下来就是实例化一个 Vuex.Store:1
2
3
4
5
6
7
8
9
10const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
}
})
Store
Store的代码位于 src/store.js 中,先看 Store 的构造函数:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59constructor (options = {}) {
// code... 省略
const {
plugins = [], // 传入的插件配置 https://vuex.vuejs.org/zh/guide/plugins.html
strict = false // 是否开启严格模式 https://vuex.vuejs.org/zh/guide/strict.html
} = options
/* 初始化内部状态 */
this._committing = false
// actions
this._actions = Object.create(null)
// 存放 actions 的订阅者
this._actionSubscribers = []
// mutations
this._mutations = Object.create(null)
// getters
this._wrappedGetters = Object.create(null)
// 模块收集
this._modules = new ModuleCollection(options)
// 模块命名空间 Map
this._modulesNamespaceMap = Object.create(null)
// 存放订阅者
this._subscribers = []
// 用以实现 Vuex.Store.watch 方法的Vue实例
this._watcherVM = new Vue()
// 绑定 commit 与 dispacth 的指向
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)
}
// 严格模式下,任何 mutation 处理函数以外修改 Vuex state 都会抛出错误。https://vuex.vuejs.org/zh/api/#strict
this.strict = strict
// 根 state
const state = this._modules.root.state
// 初始化根模块,同时递归注册所有子模块,并收集所有模块的 getters 存放到 this._wrappedGetters 中
installModule(this, state, [], this._modules.root)
// 初始化 store 的 vm,负责反应,同时将 _wrappedGetters 注册为计算属性)
resetStoreVM(this, state)
// plugins 应用插件
plugins.forEach(plugin => plugin(this))
// devtool 插件相关
const useDevtools = options.devtools !== undefined ? options.devtools : Vue.config.devtools
if (useDevtools) {
devtoolPlugin(this)
}
}
构造函数中主要是一些内部值的初始化与一些初始化方法的执行,我们按照构造函数的执行顺序由上到下分析。
ModuleCollection
首先是这一句:this._modules = new ModuleCollection(options)
,这里实例化了 ModuleCollection,用于模块收集,并处理成 Vuex 所需的数据结构。
1 | export default class ModuleCollection { |
ModuleCollection 的构造函数中从根
开始调用 this.register([], rawRootModule, false)
1 | // 注册 |
从根
开始调用 register 会实例化一个 Module 对象 new Module(rawModule, runtime)
并将其赋值给 this.root
。
这里的 Module 对象 (src/module/module.js) 是 Store 的基础数据结构
,如果使用了 module 功能,则会递归注册所有子module。
register 方法的第一个参数是路径数组,举几个例子:
- 如果未使用 module,则 path 为[],代码不会走到这里,一次注册就结束了
- 如果有一级 module,则 path 为[‘modulesName’]
- 如果有两级 module,则 path 为[‘modulesName’, grandsonModulesName]
- 依次类推 。。。。。。
对于使用了 modules 子模块的则会调用 父 Module 的 addChild 方法
添加到 父 Module 的 _children 中,最终构造出以 Module 为基础结构的树状结构
。
Module
Module 是 Store 的基础数据结构,代码不多,这里直接带注释全部贴出来:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75// Store 的基础数据结构,包含一些属性与方法
export default class Module {
constructor (rawModule, runtime) {
this.runtime = runtime
// 储存一些子模块
this._children = Object.create(null)
// 储存 rawModule
this._rawModule = rawModule
// 取出 rawModule 的 state
const rawState = rawModule.state
// 如果 rawState 是函数则执行,赋值 this.state 为函数返回值,否则赋值为 rawState 或 {}
this.state = (typeof rawState === 'function' ? rawState() : rawState) || {}
}
// 获取是否开启了 namespaced
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]
}
// 更新方法,用传入的 rawModule 的 namespaced、actions、mutations、getters替换原有的
update (rawModule) {
// 更新 namespaced
this._rawModule.namespaced = rawModule.namespaced
// 更新 actions
if (rawModule.actions) {
this._rawModule.actions = rawModule.actions
}
// 更新 mutations
if (rawModule.mutations) {
this._rawModule.mutations = rawModule.mutations
}
// 更新 getters
if (rawModule.getters) {
this._rawModule.getters = rawModule.getters
}
}
// 取出 this._children 的每个子项,以其为参数传入 fn 执行
forEachChild (fn) {
forEachValue(this._children, fn)
}
// 取出 Getter 的每个子项,以其为参数传入 fn 执行
forEachGetter (fn) {
if (this._rawModule.getters) {
forEachValue(this._rawModule.getters, fn)
}
}
// 取出 Action 的每个子项,以其为参数传入 fn 执行
forEachAction (fn) {
if (this._rawModule.actions) {
forEachValue(this._rawModule.actions, fn)
}
}
// 取出 Mutation 的每个子项,以其为参数传入 fn 执行
forEachMutation (fn) {
if (this._rawModule.mutations) {
forEachValue(this._rawModule.mutations, fn)
}
}
}
继续看构造函数
赋值 this._watcherVM 为一个 Vue 实例,用以实现 Vuex.Store.watch 方法。
1 | this._watcherVM = new Vue() |
watch 方法:1
2
3
4
5
6
7// Doc:https://vuex.vuejs.org/zh/api/#watch
watch (getter, cb, options) {
if (process.env.NODE_ENV !== 'production') {
assert(typeof getter === 'function', `store.watch only accepts a function.`)
}
return this._watcherVM.$watch(() => getter(this.state, this.getters), cb, options)
}
绑定 commit 与 dispacth 的指向
1 | const store = this |
调用 installModule 与 resetStoreVM 方法
1 | // 根 state |
插件相关
1 | // plugins 应用插件 |