vuex 源码分析_Vuex源码解析(一):Module初始化

本文深入分析Vuex的源码,主要探讨Module的初始化过程,包括installModule、makeLocalContext和resetStoreVM等关键步骤。通过这些步骤,了解Vuex如何建立模块的父子关系,如何实现数据的响应式以及getter的访问方式。Vuex通过mixin全局混入Vue实例,使$store属性在组件间共享。同时,文章揭示了在Module内部如何通过gettersProxy对象简化getter的访问,以及数据在不同层级的模块间如何流动。
摘要由CSDN通过智能技术生成

注册

install -> applyMixin->vuexInit

这里只分析Vue2的注册,因为Vue1我也没用过。

其实就是调用了Vue的静态方法mixin。静态方法mixin是全局混入,会在每一个实例的options内添加beforeCreate回调函数。

vuexInit内的options指的是每一个vue实例的options。

在最外面的App根组件上引入了store属性,因此app组件上就有了$store属性,

随后以this.store=options.parent.store = options.parent.store=options.parent.store的方式将所有vm实例的$store在组件初始化时全部指向了app根组件的store值。

即,this.$store 其实是 Store的实例。Vuex可以创建多个Store实例,但是一般而言一个Store已经够用了。

Vuex其实是一种状态管理方式,脱离了Vue也可以使用。

初始化模块(一):new Module与建立Module的父子关系

ModuleCollection构造函数:register

构造函数调用了register方法

这里根本上是根据options来创建module并且建立父子关系。具体阐述如下注释:

Module类其实内部保存的数据不多,只是一个rowModule与state而已。

初始化模块(二):installModule

installModule

获取模块的命名空间,然后递归安装所有的模块,其中有几个重要的方法要分析一下。

makeLocalContext:创建模块的本地执行上下文环境

这里传入的store为当前的store实例,命名空间为当前安装模块的命名空间,path为路径数组,root Module为[]

makeLocalContext

makeLocalGetters

使用gettersProxy代理对象,当获取模块内部的getters时,其实访问的是gettersProxy对象,gettersProxy对象做的事情就是方便在模块内部访问某一个getter时,可以不添加命名空间就可以取值。

至此,const local = (module.context = makeLocalContext(store, namespace, path))的过程已经全部清楚了

registerMutation

registerAction

registerGetters

初始化模块(三):resetStoreVM(this, state)

将getters,state加入响应式系统,只有这两个属性是因为vuex中只有这两个属性有关,action与dispatch都是改变数据的动作。

resetStoreVM,其实就做了两件事:

1. 给store添加getters属性,将所有的getter都添加到该属性内;

2. new Vue,构造函数内传入computed与data,computed值为包裹后的getters,data为state。这样getters与state的数据就加入了响应式系统。

小结

在Vuex中,数据是存储在module内部的state对象与getters对象之中。

简单来讲,可以看到store上定义了很多的内部属性,最难的部分其实是getters,因为很绕。

但是从数据获取途径的角度来看就会迎刃而解。

数据从store实例获取

初始化Vuex执行installModule的时候,registerGetter函数将原始的getter函数座一层包裹(warappedGetter),存储在store._wrappedGetters中。

执行resetStoreVM的时候,store.getters添加了store._wrappedGetters中所有的getters。

store._wrappedGetters是个中转站,工具人

通过store.getters[key]直接获取getter,值为wrappedGetter,传入了local.getters,local.state,store.getters,store.state。

所以rawGetter可以获取到上述参数。

数据从内部获取的角度

module内部的mutations对象与actions对象内的方法可以获当前module的getters/state与全局的state。

当在以module内部的视角看数据的时候,是不会在意namespace这个值的,因为在module内部就只有一个namespace。因此使用了gettersProxy对象来将当前module的getter与store实例上的getters联系起来,即gettersProxy的key不带命名空间,值为store.getters内带有命名空间的getter函数(wrappedGetter)。

local对象

local对象内有getters,为了提升性能,做了一层Cache,将getters保存到_makeLocalGettersCache对象,key为命名空间,value为gettersProxy。

local.getters

local.getters拿到了gettersProxy的值。那么将local传入wrapperedGetter函数就可以获取local的值了,同样地,传入store就可以拿到全局的值。传入其他处理后的action,dispatch就可以拿到特定的local和全局的getters/state。

所以,看起来是在内部访问的数据,其实最终还是访问了store.getters。而使用gettersProxy对象也是为了做一层缓存,并且可以在module内部取getter值的时候可以不写命名空间。

其他

在commit与dispatch的方法中含有type参数,在module内部书写type的时候,makelocalContext函数已经为type添加了namespace,因此可以直接写不带namespace的type参数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值