Vue加载后,将Vuex 加载到 Vue对象上后,初始化Store。

(一) Store的参数的定义

其中 action 与 mutation 的订阅者 用 数组存储,而其属性都是用对象存储的。

考虑了分模块存储思想,这样的存储方式个人觉得确实合理。

constructor (options = {}) {
   const {
plugins = [],
strict = false
} = options
this._committing = false //提交状态,确保 state只能在mutation的回调函数中修改
this._actions = Object.create(null) //存储用户定义的所有actions
this._actionSubscribers = []    //存储所有action的所有订阅者
this._mutations = Object.create(null) //存储用户定义的所有 mutation
this._wrappedGetters = Object.create(null) //存储用户定义的所有 getters
this._modules = new ModuleCollection(options)
this._modulesNamespaceMap = Object.create(null) // 存储命名空间,即 namespaced: true 的 module 名字都会被存储起来
this._subscribers = [] //存储所有对 mutation变化的订阅者
this._watcherVM = new Vue() //Vue对象的实例,主要利用 $watch来观测变化
}

  然后绑定 commit 与 dispatch 两个方法,指定是否严格模式;

   在严格模式下会观测所有的 state 的变化,官方建议生产环境时,传入参数 strict : false。

     const store = this
const { dispatch, commit } = this //此时的this = Stroe 实例,但是为什么这样设计
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)
}
    // enable strict mode for new vm
  if (store.strict) {
  enableStrictMode(store);
  }

难点,核心:

   installModule(this, state, [], this._modules.root); ---- 模块注册与安装

   resetStoreVM(this, state);  ----初始化store._vm,观测state和getters的变化

  整个module的创建整理有以下几个步骤:

  (一)获取 _modulesNamespaceMap 数据。

  (二)不为根模块且非热更新时,设置级联状态(太复杂,没搞懂)。

  (二)循环获取  _mutations 对象数据,其中包含了以模块划分的回调函数数组。

  (三)循环获取 _actions 对象数据,其中包含了以模块划分的回调函数数组

  (四)循环获取 _wrappedGetters对象数据,其中包含了以模块划分的回调函数数组。

    完成后,Store 如下: 

(二) mutation 的注册

  先提出个问题:

    mutation中的自定义的回调函数怎么被调用?

    让我们先回一下,我们是怎么定义自己的 store模块吧。

  

  我们定义的模块都是一个对象,每个对象的属性都有一个key值,但是value却是比较复杂的。  

  为了确保Key不重复,Vuex 开启了命名空间这个功能,即使不同的模块有相同的key值,也不会造成获取Value值被覆盖。

  而Vuex使用 Object.keys()将 可以值转换成数组,从而循环获取希望得到的数据。

module.forEachMutation(function (mutation, key) {
var namespacedType = namespace + key;
registerMutation(store, namespacedType, mutation, local);
});

从registerMutaion()函数中,可以看到,因为 store._mutations  是复杂类型,隐藏,entry.push 回调函数后,

store._mutations 立刻拥有了 模块中的 “mutation”所有属性。

而 mutations的收集,其实就是为 $store.commit 服务。

(三) this.$store.commit 定义

   当我们需要更改Store数据时,我们必须通过Mutation去修改数据状态。

      Vuex暴露接口是 $store.commit。

const { dispatch, commit } = this
this.commit = function boundCommit (type, payload, options) {
return commit.call(store, type, payload, options)
};

  Store原型上的 commit定义如下:

   

  

  

  

Vuex 源码学习(二)的更多相关文章

  1. Dubbo源码学习(二)

    @Adaptive注解 在上一篇ExtensionLoader的博客中记录了,有两种扩展点,一种是普通的扩展实现,另一种就是自适应的扩展点,即@Adaptive注解的实现类. @Documented ...

  2. Vuex 源码学习(一)

    (一)Vuex 是什么? Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态, 并以相应的规则保证状态以一种可预测的方式发生变化. —— 来自 V ...

  3. python 协程库gevent学习--gevent源码学习(二)

    在进行gevent源码学习一分析之后,我还对两个比较核心的问题抱有疑问: 1. gevent.Greenlet.join()以及他的list版本joinall()的原理和使用. 2. 关于在使用mon ...

  4. Vue源码学习二 ———— Vue原型对象包装

    Vue原型对象的包装 在Vue官网直接通过 script 标签导入的 Vue包是 umd模块的形式.在使用前都通过 new Vue({}).记录一下 Vue构造函数的包装. 在 src/core/in ...

  5. 以太坊 layer2: optimism 源码学习(二) 提现原理

    作者:林冠宏 / 指尖下的幽灵.转载者,请: 务必标明出处. 掘金:https://juejin.im/user/1785262612681997 博客:http://www.cnblogs.com/ ...

  6. [spring源码学习]二、IOC源码——配置文件读取

    一.环境准备 对于学习源码来讲,拿到一大堆的代码,脑袋里肯定是嗡嗡的,所以从代码实例进行跟踪调试未尝不是一种好的办法,此处,我们准备了一个小例子: package com.zjl; public cl ...

  7. SocketServer源码学习(二)

    SocketServer 中非常重要的两个基类就是:BaseServer 和 BaseRequestHandler在SocketServer 中也提供了对TCP以及UDP的高级封装,这次我们主要通过分 ...

  8. vuex源码分析(二) state及strict属性 详解

    state也就是vuex里的值,也即是整个vuex的状态,而strict和state的设置有关,如果设置strict为true,那么不能直接修改state里的值,只能通过mutation来设置 例1: ...

  9. Thrift源码学习二——Server层

    Thrift 提供了如图五种模式:TSimpleServer.TNonblockingServer.THsHaServer.TThreadPoolServer.TThreadSelectorServe ...

  10. mybatis源码学习(二)--mybatis+spring源码学习

    这篇笔记主要来就,mybatis是如何利用spring的扩展点来实现和spring的整合 1.mybatis和spring整合之后,我们就不需要使用sqlSession.selectOne()这种方式 ...

随机推荐

  1. iOS 视频播放方式整理

    初衷 多媒体这整个系列的文章自己也准备好开始整理了,先从视频音频最简单也是最常用的播放出发慢慢的往下深究,探索到底层的编码解码等等,这篇文章就从视频的播放这个最简单的说起. iOS的视频播放方式有几种 ...

  2. upload 上传类

    <?php/**file: fileupload.class.php 文件上传类FileUpload本类的实例对象用于处理上传文件,可以上传一个文件,也可同时处理多个文件上传 */class U ...

  3. SQL Server学习之路(五):“增删改查”之“改”

    0.目录 1.前言 2.通过SSMS修改数据 3.通过SQL语句修改数据 3.1 修改单列数据 3.2 修改多列数据 1.前言 增删改查都是对数据的操作,其中"改"对应的SQL语句 ...

  4. git以及github的初级入门(一)

    本身学习git的操作是没什么兴趣的,毕竟原本是win平台学的java开发,git下那么多复制的命令行操作确实比较让人头疼,直到昨天我打开计算机的时候,我放置项目的E盘,以及F盘,G盘盘符都不见了!!我 ...

  5. lua游戏开发实践指南学习笔记1

    本文是依据lua游戏开发实践指南做的一些学习笔记,仅用于继续自己学习的一些知识. Lua基础 1.  语言定义: 在lua语言中,标识符有非常大的灵活性(变量和函数名),只是用户不呢个以数字作为起始符 ...

  6. C#线程等待句柄

    相互排斥对象 Mutex private Mutex m = new Mutex(); public void Method(){ m.WaitOne(); //运行操作 m.ReleaseMutex ...

  7. IIS 服务或万维网公布服务,或者依赖这 服务可能在启动期间错误发生或者已禁用

    作者:jiankunking 出处:http://blog.csdn.net/jiankunking 详细错误信息例如以下: 解决方式: 在服务中禁用下面3个服务自己主动启动: Net.Msmq Li ...

  8. 快看Sample代码,速学Swift语言(1)-语法速览

    Swift是苹果推出的一个比较新的语言,它除了借鉴语言如C#.Java等内容外,好像还采用了很多JavaScript脚本里面的一些脚本语法,用起来感觉非常棒,作为一个使用C#多年的技术控,对这种比较超 ...

  9. Javaweb 项目内所有页面都是404问题

    这两天出现的问题:项目内所有的页面都是404 问题原因:Tomcat在启动时出现了问题导致服务器根本没启动起来 问题的根本原因: 由于之前用到了拦截器,然后拦截器没用了被我删掉了,但是web.xml文 ...

  10. 自学Python5.2-类、模块、包

    类.模块.包  一.类 类的概念在许多语言中出现,很容易理解.它将数据和操作进行封装,以便将来的复用. 二.模块module 通常模块为一个文件,直接使用import来导入就好了.可以作为module ...