手撕Vuex-安装模块方法

前言
经过上一篇文章的介绍,我们实现了将模块安装到 store 中,那么本章我们就来介绍一下怎么安装模块当中的方法也就是 actions、mutations、getters。
所以本次文章的目标就是将模块当中的 actions、mutations、getters 安装到 store 中,然后在组件中使用。
分析阶段
那么安装 actions、mutations、getters 就不能在 Store 的构造函数进行调用安装方法进行安装了。
为什么呢,因为你在使用构造函数进行调用安装方法是拿不到我们的子模块的,所以我们该怎么改造呢?
首先我将这三个 init 方法剪切了:

然后我们是不是可以在 installModule 方法当中进行安装呢?
我的回答是可以的,我们可以在 installModule 方法当中进行安装。
我们在 initModule 方法当中遍历取出了所有的子模块,在这个方法中我们就可以拿到所有的子模块,所以说我觉得在这里安装 actions、mutations、getters 是最好的,更为合适的。
代码实现
那么我们该给 initActions、initMutations、initGetters 传递什么参数呢?之前传递的是 options 选项,现在我们传递的是 module 模块,因为我们在 installModule 方法当中已经拿到了 module 模块,所以我们直接将 module 模块传递给 initActions、initMutations、initGetters 就可以了。
当前模块保存到了当前传递进来参数的 _raw 属性上面,改造之后的代码如下:

由于增加了我们的一个子模块所以,我们的 initActions、initMutations、initGetters 方法是需要进行微调的,首先我们来微调 initGetters 方法,由于这个方法会被多次调用,所以说我们首先进入到方法当中进行分析,在 getters 当中由于它多次被调用,是不是说新增过了 getters 就不需要再次新增了,所以说我们需要判断一下,如果说当前的 getters 已经存在了,那么就不需要再次新增了,如果说当前的 getters 不存在,那么就需要新增。改造之后的代码如下:

逻辑非常的简单,就是如果有就返回,没有就返回一个空对象,这个呢就是我们 getters 需要做的改变。
然后呢,我们在来看一下 actions 和 mutations,这两个方法有什么改变,和刚才一样,由于它会被多次调用,所以说在 mutations 当中,如果说当前的 mutations 已经存在了,那么就不需要再次新增了,如果说当前的 mutations 不存在,那么就需要新增。改造之后的代码如下:

actions 同理可证一样的逻辑,自己添加一下别忘记了,不然会导致 "TypeError: Cannot read properties of undefined (reading 'forEach')" 会重新开辟一个新的 actions 所以就不会按照我之前分析的思路去走逻辑了,创建了 mutations 之后,在之前的文章当中我有介绍到,mutations 与 actions 当中的方法是可以重复的,也就是说在子模块当中定义的方法是不会覆盖掉根模块当中的方法的,所以说我们在这里需要将子模块当中的方法与根模块当中的方法进行合并,合并之后的方法是一个数组,然后在执行这个数组当中的方法,这样就可以了。
所以我们要改造的就是在添加方法的时候进行改造代码,首先我们拿到对应名称的方法,先去获取一下看看有没有对应名称的方法,看看有没有,如果说没有,我们就返回一个空数组,后续就是用这个数组来保存同名的方法,那这里改为了用数组来保存同名的方法,那么就不是直接赋值了,这里应该改造为往这个名称的数组当中添加方法,改造之后的代码如下:

// 2.在Store上新增一个mutations的属性
this.mutations = this.mutations || {};
// 3.将传递进来的mutations中的方法添加到当前Store的mutations上
for (let key in mutations) {
this.mutations[key] = this.mutations[key] || [];
this.mutations[key].push((payload) => {
// 4.将mutations中的方法执行, 并且将state传递过去
mutations[key](this.state, payload);
});
}
actions 同理可证,改造之后的代码如下:

好了到这里还没完,我们目前已经将所有的方法放入到数组当中了,那么以后我们怎么执行这一步我们是不是还需要改造一下,我们在 commit 的时候,我们是不是需要将这个数组当中的方法执行一下,那么我们就需要改造一下 commit 方法,改造之后的代码如下:
commit = (type, payload) => {
this.mutations[type].forEach(fn => fn(payload));
}
dispatch 方法也是一样的,改造之后的代码如下:
dispatch = (type, payload) => {
this.actions[type].forEach(fn => fn(payload));
}
测试
好了到这里我们的代码就改造完毕了,我们来找一个组件来测试一下,将我们之前的测试共享数据的注释代码放开,页面效果如下:

发现 getters 是 undefined,好了我们回到代码来看看到底是怎么回事引起的,找到我们的 getters,发现我们给的 state 是不对的,我们应该将当前模块的 state 传递进去,改造之后的代码如下:
return getters[key](options.state);
刷新页面就会发现已经好了,那么我们的 actions 和 mutations 也是一样的:
mutations[key](options.state, payload);
actions 没有用到所以这里我们就不用管它。好了到这里我觉得我编写的代码已经没有问题了,我们来看一下页面效果,这里我录制一个 gif 图片,方便大家观看:

最后

手撕Vuex-安装模块方法的更多相关文章
- python安装模块方法汇总
方法一: 原文地址: http://blog.csdn.net/cighao/article/details/47860041 在 windows 系统下,只需要输入命令 pip install re ...
- Node-webkit 安装使用npm安装模块方法
原文链接:http://jingyan.baidu.com/article/5225f26b5aaa20e6fa0908a6.html package.json可以放在软件根目录下,也可以放在项目目录 ...
- pycharm安装模块方法
一. 打开pycharm 二. 点开file 三. 点击Settings,点击Project Interpreter,选择右上角+ 四. 进入后,在搜索框搜索需要安装的模块,选中安装 击Project ...
- pip安装python模块方法
网上搜索了很多,主流的配置方法分为两种: 摘自 1.http://www.jb51.net/article/83617.htm 安装pip的包并确定pip安装时的镜像源地址,国内常用的地址有: htt ...
- 扩展的方法:es6 安装模块builder
https://github.com/es-shims/es5-shim/ Image.png 检测浏览器可支持es5,不支持就扩展,做兼容: 扩展的方法: Image.png 取所有对象的键值: o ...
- 编译原理--05 用C++手撕PL/0
前言 目录 01 文法和语言.词法分析复习 02 自顶向下.自底向上的LR分析复习 03 语法制导翻译和中间代码生成复习 04 符号表.运行时存储组织和代码优化复习 05 用C++手撕PL/0 在之前 ...
- NN入门,手把手教你用Numpy手撕NN(一)
前言 这是一篇包含极少数学推导的NN入门文章 大概从今年4月份起就想着学一学NN,但是无奈平时时间不多,而且空闲时间都拿去做比赛或是看动漫去了,所以一拖再拖,直到这8月份才正式开始NN的学习. 这篇文 ...
- 手写Vuex源码
Vuex原理解析 Vuex是基于Vue的响应式原理基础,所以无法拿出来单独使用,必须在Vue的基础之上使用. 1.Vuex使用相关解析 main.js import store form './s ...
- java实现二叉树的Node节点定义手撕8种遍历(一遍过)
java实现二叉树的Node节点定义手撕8种遍历(一遍过) 用java的思想和程序从最基本的怎么将一个int型的数组变成Node树状结构说起,再到递归前序遍历,递归中序遍历,递归后序遍历,非递归前序遍 ...
- python 安装模块
python安装模块的方法很多,在此仅介绍一种,不需要安装其他附带的pip等,python安装完之后,配置环境变量,我由于中英文分号原因,环境变量始终没能配置成功汗. 1:下载模块的压缩文件解压到任意 ...
随机推荐
- Django:TypeError: view must be a callable or a list/tuple in the case of include().
错误: path("uploads/(?P<path>.*)$", 'django.views.static.serve', {"document_root& ...
- Python工具箱系列(三十九)
使用zlib对数据进行压缩 现实世界中,大量存在着对数据压缩的需求.为此,python内置了zlib压缩库,可以方便的对任意对象进行压缩. 下述代码演示了对字符串进行压缩: import zlib # ...
- Oracle内存管理方式介绍(转载)
"Oracle内存管理可分为两大类,自动内存管理和手动内存管理.其中手动内存管理又可分为自动共享内存管理,手动共享内存管理,自动PGA内存管理以及手动PGA内存管理.本文会简单的介绍不同的内 ...
- WPF 入门笔记 - 07 - MVVM示例
滴咚,大家好久不见.好就没写东西了,鸽着鸽着就无了... 回到正题,上篇文章说完命令提了一嘴MVVM模式直接就上MVVMLight这些程序的框架了,虽然也没说多少,但还是有点不好过渡,这篇对MVVM做 ...
- __wakeup()魔术方法绕过(CVE-2016-7124)
__wakeup()魔术方法绕过(CVE-2016-7124) 漏洞简介 在php反序列化数据过程中,如果类中存在__wakeup方法,调用 unserilize() 方法前则先调用__wakeup方 ...
- Robot 框架学习笔记
Robot 框架学习笔记 为了更好地让读者理解快速学习新框架的思路,笔者接下来会继续介绍另一个名为 Robot 的自动化测试框架,希望读者能参考笔者从零开始讲解一个开发/测试框架的流程,从中总结出适合 ...
- Solution -「洛谷 P1852」跳跳棋
Description Link. 在一个数轴上给你三个点,移动方法是彼此为中点进行跳跃,不能同时越过两颗棋子. 给出初始状态和目标状态,问能否从初始状态跳到目标状态.若能,输出最少步数. 棋子之间互 ...
- paramiko免密登陆
paramiko免密登陆 # -*- coding: utf-8 -*- import paramiko pkey='D:/pycharm_workspace/testpy/ssh_paramiko_ ...
- Vitess全局唯一ID生成的实现方案
为了标识一段数据,通常我们会为其指定一个唯一id,比如利用MySQL数据库中的自增主键. 但是当数据量非常大时,仅靠数据库的自增主键是远远不够的,并且对于分布式数据库只依赖MySQL的自增id无法满足 ...
- Go语言常用标准库——flag
文章目录 os.Args flag包基本使用 导入flag包 flag参数类型 定义命令行flag参数 flag.Type() flag.TypeVar() flag.Parse() flag其他函数 ...