之前看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 statethis._committing = false// 用来寄存解决后的用户自定义的actoinsthis._actions = Object.create(null)// 用来寄存 actions 订阅this._actionSubscribers = []// 用来寄存解决后的用户自定义的mutationsthis._mutations = Object.create(null)// 用来寄存解决后的用户自定义的 gettersthis._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 selfconst store = thisconst { dispatch, commit } = thisthis.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
实例。
// 严格模式,默认是falsethis.strict = strict// 根模块的stateconst state = this._modules.root.state// init root module.// this also recursively registers all sub-modules// and collects all module getters inside this._wrappedGettersinstallModule(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
版本逻辑简直截然不同,疏忽。