手撕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:下载模块的压缩文件解压到任意 ...
随机推荐
- DXP TreeList 目录树
DXP TreeList 目录树 1.需求背景 需要一个支持勾选,拖动节点,保存各节点顺序的目录树. 2.创建目录树 在treeList控件中添加两个colunm 用来显示绑定数据和显示值. 接下来对 ...
- Node.js安装中出现的问题及其解决方案
Node.js安装与配置流程,请参考 1.npm -v测试时出现警告 更好的选择是安装一个更完善的版本 问题出现的原因 node更新后是最新版 但是npm的版本没有相应的更新存在版本滞后导致问题出现 ...
- 【Unity3D】调整屏幕亮度、饱和度、对比度
1 屏幕后处理流程 调整屏幕亮度.饱和度.对比度,需要使用到屏幕后处理技术.因此,本文将先介绍屏幕后处理流程,再介绍调整屏幕亮度.饱和度.对比度的实现. 本文完整资源见→Unity3D调整屏幕 ...
- Linux 身份验证被拒绝,登录失败解决
解决方案: vim /etc/ssh/sshd_config 修改参数 基本参数: PermitRootLogin yes #允许root认证登录 PasswordAuthentication yes ...
- 2.go语言基础类型漫游
本篇前瞻 本篇是go语言的基础篇,主要是帮助大家梳理一下go语言的基本类型,注意本篇有参考go圣经,如果你有完整学习的需求可以看一下,另外,go语言的基本类型比较简单,介绍过程就比较粗暴. 基本类型 ...
- 安装win10虚拟机
1.前期工作 下载win10镜像:zh-cn_windows_10_consumer_editions_version_21h1_updated_aug_2021_x64_dvd_4de56d76.i ...
- .NET Evolve 数据库版本管理工具
.NET Evolve数据库版本管理工具 1.简介 提到数据库版本管理,Java领域开发首先会想到大名鼎鼎的flyway.但是它不适用.NET领域,那么.NET领域也需要做数据库版本管理,该用什么工具 ...
- Android RIL&IMS源码分析
一.需求 1.了解IMS相关知识体系 2.RILD 与 RILJ.IMS回调消息的机制 二.相关概念 2.1 IMS IMS全称是IP Multimedia Subsystem,中文意义为IP多媒体子 ...
- 系统内存管理:虚拟内存、内存分段与分页、页表缓存TLB以及Linux内存管理
虚拟内存 虚拟内存是一种操作系统提供的机制,用于将每个进程分配的独立的虚拟地址空间映射到实际的物理内存地址空间上.通过使用虚拟内存,操作系统可以有效地解决多个应用程序直接操作物理内存可能引发的冲突问题 ...
- python如何提取浏览器中保存的网站登录用户名密码
python如何提取Chrome中的保存的网站登录用户名密码? 很多浏览器都贴心地提供了保存用户密码功能,用户一旦开启,就不需要每次都输入用户名.密码,非常方便.作为python脚本,能否拿到用户提前 ...