之前看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,strictdevtools.

// 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)}

dispatchcommit函数绑定thisstore实例。

// 严格模式,默认是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版本逻辑简直截然不同,疏忽。

resetStoreState(重要)