之前看 vuex 的 3.x 版本源码,当初看下 4.x 版本源码有哪些不同?还是针对外围源码
Vuex 是一个专为 Vue.js 利用程序开发的 状态管理模式 + 库。它采纳集中式存储管理利用的所有组件的状态,并以相应的规定保障状态以一种可预测的形式发生变化。
所以跟 3.x 版本,
- 官网示例代码
import {createApp} from 'vue'
import {createStore} from 'vuex'
// 创立一个新的 store 实例
const store = createStore({state () {
return {count: 0}
},
mutations: {increment (state) {state.count++}
}
})
const app = createApp({/* 根组件 */})
// 将 store 实例作为插件装置
app.use(store)
createStore
export function createStore (options) {return new Store(options)
}
createStore
函数很简略,间接返回一个 Sotre
示例。
Sotre 类
app.use
会调用传入参数对象的 install
函数,所以先来剖析 install
函数
install 函数
export const storeKey = 'store'
install (app, injectKey) {
// 设置 sotre 实例到利用范畴中的所有组件
app.provide(injectKey || storeKey, this)
// 增加 $store 属性作为全局的 property, 相当于 Vue.prototype.$store
app.config.globalProperties.$store = this
// 疏忽
const useDevtools = this._devtools !== undefined
? this._devtools
: __DEV__ || __VUE_PROD_DEVTOOLS__
if (useDevtools) {addDevtools(app, this)
}
}
install
函数首先应用 Vue 的依赖注入 provide
来挂载 sotre
实例,为什么要这么做?因为在 setup
办法中无法访问this
。
构造函数
export class Store {constructor (options = {}) {// 还是跟之前一样逐渐剖析}
}
if (__DEV__) {assert(typeof Promise !== 'undefined', `vuex requires a Promise polyfill in this browser.`)
assert(this instanceof Store, `store must be called with the new operator.`)
}
1. 以后环境不反对 Promise,报错:vuex 须要 Promise polyfill。
2.Store 函数必须应用 new 操作符调用。
const {plugins = [],
strict = false,
devtools
} = options
从定义的 options
取出 plugins
,strict
和devtools
.
// store internal state
this._committing = false
// 用来寄存解决后的用户自定义的 actoins
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)
// 用于存储模块命名空间的关系
this._modulesNamespaceMap = Object.create(null)
// 订阅
this._subscribers = []
// 用来寄存生成的本地 getters 的缓存
this._makeLocalGettersCache = Object.create(null)
this._devtools = devtools
这一块跟 vuex@3.x
简直截然不同。就删除了_watcherVM
// bind commit and dispatch to self
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)
}
dispatch
和 commit
函数绑定 this
为store
实例。
// 严格模式,默认是 false
this.strict = strict
// 根模块的 state
const state = this._modules.root.state
// init root module.
// this also recursively registers all sub-modules
// and collects all module getters inside this._wrappedGetters
installModule(this, state, [], this._modules.root)
// initialize the store state, which is responsible for the reactivity
// (also registers _wrappedGetters as computed properties)
resetStoreState(this, state)
// apply plugins
// 插件:把实例对象 store 传给插件函数,执行所有插件。plugins.forEach(plugin => plugin(this))
installModule
函数,初始化根模块,并且递归遍历所有子模块,并且收集所有模块的 gettter
搁置在 _wrappedGetters
中。
resetStoreState
函数,初始化 store.state 响应式,并且注册
_wrappedGetters 作为 它的
computed` 的属性。
installModule
这里跟 vuex@3.x
版本逻辑简直截然不同,疏忽。