【源码】[email protected]

之前看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 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

这一块跟[email protected]几乎一模一样。就删除了_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

这里跟[email protected]版本逻辑几乎一模一样,忽略。

resetStoreState(重要)

你可能感兴趣的:(vuex源码分析)