Vuex源码解析之store初始化

本文深入探讨Vuex的Store初始化过程,包括构造函数中的关键步骤:模块初始化、安装模块以及初始化store._vm。通过分析ModuleCollection和Module类,展示了如何构建模块树,并解释了installModule函数如何完成actions、mutations和getters的注册。最后,介绍了resetStoreVM如何建立getters和state之间的依赖关系,确保getter的实时更新。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

“ 我们知道,vuex是一个专门为vue.js设计的状态管理器。它可以集中存储所有组件的状态,让兄弟组件或多层嵌套组件之间的传值变得简单。vuex以全局单例模式管理着所有组件的状态和一些触发状态变化的行为,本篇从源码上详解vuex是如何设计这个store单例,也就是store类实例化的过程。”


下面看一个最简单的例子:

import Vue from 'vue'
import Vuex from 'vuex'
​
Vue.use(Vuex)
​
const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  }
})


它最终形成的初始化的store实例对象如下图:

图1

可以看到形成的store对象中保存了commit、dispatch两个方法和getters、actions、mutations、modules、modulesNamespaceMap等等属性。下面我们看一下vuex是如何定义这些属性与方法的。

看一下store构造函数,它接收一个对象参数,里面包含actions、getters、state、mutations、modules等Vuex的核心概念。

export class Store {
  constructor (options = {}) {
    // Auto install if it is not done yet and `window` has `Vue`.
    // To allow users to avoid auto-installation in some cases,
    // this code should be placed here. See #731
    if (!Vue && typeof window !== 'undefined' && window.Vue) {
      install(window.Vue)
    }
​
    // ...
​
    const {
      plugins = [],
      strict = false
    } = options
​
    // store internal state
    this._committing = false
    this._actions = Object.create(null)
    this._actionSubscribers = [] // 订阅actions变化的订阅者
    this._mutations = Object.create(null)
    this._wrappedGetters = Object.create(null)
    this._modules = new ModuleCollection(options) // 初始化modules。构建一个modules树。
    this._modulesNamespaceMap = Object.create(null)
    this._subscribers = [] // 订阅mutations变化的订阅者
    this._watcherVM = new Vue()
    this._makeLocalGettersCache = Object.create(null)
​
    // 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.dispatch时,保证dispatch上下文是store
    this.commit = function boundCommit (type, payload, options) {
      return commit.call(store, type, payload, options)
    }
​
    // strict mode
    this.strict = strict
​
    const state = this._modules.root.state
    // 安装模块
    installModule(this, state, [], this._modules.root)
    // getters和state建立依赖关系,变成响应式
    resetStoreVM(this, state)
​
    // apply plugins
    plugins.forEach(plugin => plugin(this))
​
    const useDevtools = options.devtools !== undefined ? options.devtools : Vue.config.devtools
    if (useDevtools) {
      devtoolPlugin(this)
    }
  }
  ...
}


以上构造函数逻辑,我们会重点关注到三个点:

this._modules = new ModuleCollection(options):modules初始化模块,形成一棵modules树,最终会存储在图1的_modules属性中.

installModule(this, state, [], this._modules.root):安装模块

resetStoreVM resetStoreVM(this, state):初始化store._vm

初始化模块

假设我们定义了下面这个store,这个store中包含了一个根模块和两个子模块moduleA和moduleB。

const moduleA = {
  namespace: true,
  state: { c: 2 },
  mutations: { ... },
  actions: { ... },
  getters: { ... }
}
​
const moduleB = {
  state: { d: 4 },
  mutations: { ... },
  actions: { ... },
  getters: { ... },
}
​
const store = new Vuex.Store({
  modules: {
    a: moduleA,
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值