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. 数据库sql语句总结

    1) select 字段名 from 表名 group by 字段名(或是多个字段名,中间用逗号隔开) having count(*)>1:查询表中某一(某几个)字段内的重复数据 Oracle: ...

  2. javascript面向对象系列第四篇——OOP中的常见概念

    前面的话 面向对象描述了一种代码的组织结构形式——一种在软件中对真实世界中问题领域的建模方法.本文将从理论层面,介绍javascript面向对象程序程序(OOP)中一些常见的概念 对象 所谓对象,本质 ...

  3. 分享一个好用的微信npmjs包

    https://www.npmjs.com/package/jquery_wechat_sdk 安装 $ npm install jquery_wechat_sdk 使用 Browser Script ...

  4. 使用fastdfs-zyc监控FastDFS文件系统

    1.安装jdk运行环境 jdk下载地址:http://www.oracle.com/technetwork/java/javase/downloads/index.html 此处我使用的jdk7U99 ...

  5. Vue.js学习 — 微信公众号菜单编辑器(一)

    学习里一段时间Vue.js,于是想尝试着做一个像微信平台里那样的菜单编辑器,在这里分享下 具体样式代码查看项目github 创建一个vue实例 <!DOCTYPE html> <ht ...

  6. Okio 之初探黄龙

    Okio 是一个包装了 java.io 和 java.nio api 的库,以便可以更容易的访问.存储以及处理数据. ByteStrings 和 Buffers Okio 是围绕着两个容器类构建起来的 ...

  7. Linux分区的注意事项以及远程连接排错

    分区方式一般有三种 第一种:数据不是很重要 /boot(系统的引导分区): 系统引导的信息/软件 系统的内核   200M swap( 交换分区): 为了避免系统内存用光了导致系统 宕机 如果系统内存 ...

  8. EGOCache缓存框架具体解说

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/ ...

  9. 使用milang出错:LookupError: unknown encoding: idna

    今天同事安装了milang,结果发现例如以下出错: Traceback (most recent call last): File "F:\vmid.py", line 11, i ...

  10. iOS 从应用程序跳转到评价界面

    1,跳转到App Store: NSString *str = [NSString stringWithFormat:@"http://itunes.apple.com/us/app/id% ...