【源码】vuex@4.0.2

之前看vuex 的 3.x 版本源码,现在看下4.x版本源码有哪些不同?还是针对核心源码
【【源码】vuex@4.0.2】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,strictdevtools.
// 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) }

dispatchcommit函数绑定thisstore实例。
// 严格模式,默认是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版本逻辑几乎一模一样,忽略。
resetStoreState(重要)

    推荐阅读