Vuex 源码学习(二)
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 源码学习(二)的更多相关文章
- Dubbo源码学习(二)
@Adaptive注解 在上一篇ExtensionLoader的博客中记录了,有两种扩展点,一种是普通的扩展实现,另一种就是自适应的扩展点,即@Adaptive注解的实现类. @Documented ...
- Vuex 源码学习(一)
(一)Vuex 是什么? Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态, 并以相应的规则保证状态以一种可预测的方式发生变化. —— 来自 V ...
- python 协程库gevent学习--gevent源码学习(二)
在进行gevent源码学习一分析之后,我还对两个比较核心的问题抱有疑问: 1. gevent.Greenlet.join()以及他的list版本joinall()的原理和使用. 2. 关于在使用mon ...
- Vue源码学习二 ———— Vue原型对象包装
Vue原型对象的包装 在Vue官网直接通过 script 标签导入的 Vue包是 umd模块的形式.在使用前都通过 new Vue({}).记录一下 Vue构造函数的包装. 在 src/core/in ...
- 以太坊 layer2: optimism 源码学习(二) 提现原理
作者:林冠宏 / 指尖下的幽灵.转载者,请: 务必标明出处. 掘金:https://juejin.im/user/1785262612681997 博客:http://www.cnblogs.com/ ...
- [spring源码学习]二、IOC源码——配置文件读取
一.环境准备 对于学习源码来讲,拿到一大堆的代码,脑袋里肯定是嗡嗡的,所以从代码实例进行跟踪调试未尝不是一种好的办法,此处,我们准备了一个小例子: package com.zjl; public cl ...
- SocketServer源码学习(二)
SocketServer 中非常重要的两个基类就是:BaseServer 和 BaseRequestHandler在SocketServer 中也提供了对TCP以及UDP的高级封装,这次我们主要通过分 ...
- vuex源码分析(二) state及strict属性 详解
state也就是vuex里的值,也即是整个vuex的状态,而strict和state的设置有关,如果设置strict为true,那么不能直接修改state里的值,只能通过mutation来设置 例1: ...
- Thrift源码学习二——Server层
Thrift 提供了如图五种模式:TSimpleServer.TNonblockingServer.THsHaServer.TThreadPoolServer.TThreadSelectorServe ...
- mybatis源码学习(二)--mybatis+spring源码学习
这篇笔记主要来就,mybatis是如何利用spring的扩展点来实现和spring的整合 1.mybatis和spring整合之后,我们就不需要使用sqlSession.selectOne()这种方式 ...
随机推荐
- 数据库sql语句总结
1) select 字段名 from 表名 group by 字段名(或是多个字段名,中间用逗号隔开) having count(*)>1:查询表中某一(某几个)字段内的重复数据 Oracle: ...
- javascript面向对象系列第四篇——OOP中的常见概念
前面的话 面向对象描述了一种代码的组织结构形式——一种在软件中对真实世界中问题领域的建模方法.本文将从理论层面,介绍javascript面向对象程序程序(OOP)中一些常见的概念 对象 所谓对象,本质 ...
- 分享一个好用的微信npmjs包
https://www.npmjs.com/package/jquery_wechat_sdk 安装 $ npm install jquery_wechat_sdk 使用 Browser Script ...
- 使用fastdfs-zyc监控FastDFS文件系统
1.安装jdk运行环境 jdk下载地址:http://www.oracle.com/technetwork/java/javase/downloads/index.html 此处我使用的jdk7U99 ...
- Vue.js学习 — 微信公众号菜单编辑器(一)
学习里一段时间Vue.js,于是想尝试着做一个像微信平台里那样的菜单编辑器,在这里分享下 具体样式代码查看项目github 创建一个vue实例 <!DOCTYPE html> <ht ...
- Okio 之初探黄龙
Okio 是一个包装了 java.io 和 java.nio api 的库,以便可以更容易的访问.存储以及处理数据. ByteStrings 和 Buffers Okio 是围绕着两个容器类构建起来的 ...
- Linux分区的注意事项以及远程连接排错
分区方式一般有三种 第一种:数据不是很重要 /boot(系统的引导分区): 系统引导的信息/软件 系统的内核 200M swap( 交换分区): 为了避免系统内存用光了导致系统 宕机 如果系统内存 ...
- EGOCache缓存框架具体解说
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/ ...
- 使用milang出错:LookupError: unknown encoding: idna
今天同事安装了milang,结果发现例如以下出错: Traceback (most recent call last): File "F:\vmid.py", line 11, i ...
- iOS 从应用程序跳转到评价界面
1,跳转到App Store: NSString *str = [NSString stringWithFormat:@"http://itunes.apple.com/us/app/id% ...