手撕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:下载模块的压缩文件解压到任意 ...
随机推荐
- 【做题笔记】树形 dp
luoguP1122 最大子树和 Solve 设计状态 \(dp[i]\) 表示子树 \(i\) 的最大点权和,则有: 当 \(dp[son[i]] > 0\) 时,选以 \(son[i]\) ...
- 【go笔记】简单的http服务
前言 Go语言通过内置的标准库net/http可以非常方便地实现web服务.不借助任何框架,单凭标准库,50行代码内即可实现简单的web服务. http的ListenAndServe()函数原型: f ...
- 【LaTeX】制作 PPT(更新中)
目录 Beamer 模板 特性 frame 与 slide \pause itemize 中的尖括号 <strat-end> 参考资料 Beamer 模板 PPT 推荐用 Beamer 模 ...
- 搭建LNMP 架构
搭建LNMP 架构 环境准备 lnmp 需要 安装 nginx mysql php 软件 #关闭防火墙 systemctl disable --now firewalld #临时禁用SELinux的强 ...
- ORM查询一个表中有两个字段相同时,只获取某个值最大的一条
Table表如下: 获取表中name和hex值相同时age最大的那一条 ORM写法,两次查询 ids = table.values('name', 'age').annotate(id=Max('id ...
- CCF 202012-5星际旅行(20~100分)
前置知识 线段树:通过懒惰标记,可实现区间处理,和区间询问皆为\(O(logn)\)时间复杂度的数据结构,是一种二叉树.因此对于一个节点\(st\),其左儿子节点为\(st*2\),右节点为\(st* ...
- CodeForces 1367F2 Flying Sort (Hard Version)
题意 给一个长度为\(n\)的数组,你可以有两种操作 将某一个数放置在数组开头 将某一个数放置在数组结尾 问最小操作多少次可以得到一个非递减数列 (比\(F1\)难在\(n\)变大,且数组中元素可以有 ...
- Ipa打包并安装到iphone
手动运行篇: 在真机上运行appium会进行闪退,因为我们的真机是不合法的真机,怎么样才能合法呢,要注册我们的设备才行 要对app进行打包,要先进行签名,要签名,就需要证书,证书可以自己伪造,但是这一 ...
- Record - Dec. 1st, 2020 - Exam. REC
Prob. 1 Desc. & Link. 行走的形式是比较自由的,因为只要走到了最优答案处就可以不管了,所以不需要考虑游戏的结束. 考虑二分答案. 然后预处理出每个节点到 \(s\)(另一棵 ...
- Solution -「CF 1073G」Yet Another LCP Problem
Description Link. 给定字符串,正整数集合 \(A,B\),满足 \(\forall u\in A,v\in B,1\le u,v\le n\). 求 \(\sum_{i\in A}\ ...