经过上一篇章介绍,完成了实现 mutations 的功能,那么接下来本篇将会实现 actions 的功能。

本篇我先介绍一下 actions 的作用,然后再介绍一下实现的思路,最后再实现代码。

actions 的作用是用来异步修改共享数据的,怎么异步修改,这个时候我们回到 Vue 的官方 Vuex 文档中,有如下这么一个图:

从图中可以看出,我们在组件中调用 dispatch 方法,然后 dispatch 方法会调用 actions,然后 actions 中的方法可以通过 commit 会调用 mutations 中的方法,最后 mutations 中的方法会修改 state 中的数据,这就是 actions 的作用。

这里我们先来回顾一下怎么使用 actions,再来实现一遍即可。

  1. 将官方的 Vuex 注释放开
  2. 在 store 中定义 age
  3. 在 mutations 中定义 changeAge 方法
  4. 在 actions 中定义 asyncAddAge 方法 (页面通过 dispatch 调用 actions 中的方法, actions 中的方法通过 commit 调用 mutations 中的方法)

如上是我本次实现的思路,接下来我们来实现代码。

我这里直接贴出代码, 代码中有详细的注释, 代码如下:

1. 略过

2. 定义 age
state: {
age: 0
} 3. 在 mutations 中定义 changeAge 方法
/**
* 通过dispatch调用
* @param state 仓库的state
* @param payload 载荷
*/
addAge(state, payload) {
state.age += payload;
} 4. 在 actions 中定义 asyncAddAge 方法
/**
* 通过dispatch调用
* @param commit 提交
* @param payload 载荷
*/
asyncAddAge({commit}, payload) {
// 模拟异步操作
setTimeout(() => {
// 通过commit调用mutations中的方法
commit('addAge', payload);
}, 3000);
}
  1. 在组件中通过 dispatch 调用 actions 中的方法(HelloWorld 组件)
// 显示数据
<p>{{ this.$store.state.age }}</p> // 调用actions中的方法
<button @click="myFn">我是按钮</button>
myFn() {
this.$store.dispatch('asyncAddAge', 10);
},

npm run serve 启动项目,点击按钮,3 秒后 age 的值加 10,说明 actions 的功能实现了。效果如下图:

到此为止,回顾完成了之后,我们就可以开始实现 actions 的功能了。

actions 的实现思路和 mutations 的实现思路是一样的,首先将官方的 Vuex 注释掉,导入我们自己的 Nuex:

import Vuex from './Nuex'
// import Vuex from 'vuex'

回到我们的 Nuex 文件中,和之前一样先将 actions 保存到 Store 上,我这里单独弄了一个 initActions 方法,代码如下:

// 将传递进来的 actions 放到 Store 上
this.initActions(options);

initActions 方法的实现如下:

initActions(options) {
// 1.拿到传递进来的actions
let actions = options.actions || {};
// 2.在Store上新增一个actions的属性
this.actions = {};
// 3.将传递进来的actions中的方法添加到当前Store的actions上
for (let key in actions) {
this.actions[key] = (payload) => {
// 4.将actions中的方法执行, 并且将当前Store实例传递过去
actions[key](this, payload);
}
}
}

这里和 mutations 的实现思路是一样的,只是将 mutations 换成了 actions,然后将传递进来的 actions 中的方法添加到当前 Store 的 actions 上,最后将 actions 中的方法执行,并且将当前 Store 实例传递过去。

测试一下看看有没有添加到 Store 上,运行项目,测试结果如下:

可以看到 actions 已经添加到 Store 上了,那么在页面上是通过 dispatch 调用 actions 中的方法,所以我们需要在 Store 上添加 dispatch 方法,代码如下:

dispatch = (type, payload) => {
this.actions[type](payload);
}

这里和 mutations 的实现思路是一样的,只是将 commit 换成了 actions,然后将传递进来的 actions 中的方法执行,并且将当前 Store 实例传递过去。

运行项目,测试结果如下:

Uncaught TypeError: Cannot read properties of undefined (reading 'mutations')

这里报错了,其实这个问题我已经知道错在哪里了,我先带着大家看一下这个调用流程,然后再解决这个问题。

  1. 在组件中调用 dispatch 方法,我传递是的 'asyncAddAge', 10

  1. 在 dispatch 方法中,我拿到了传递进来的 type,也就是 'asyncAddAge', payload 也就是 10, 然后调用了 actions 中的方法

  1. 在 actions 中的方法中,我拿到了传递进来的 payload,也就是 10,在 asyncAddAge 方法中,我调用了 commit 方法,也就是调用了 mutations 中的方法

  1. 在 commit 方法中,我拿到了传递进来的 type,也就是 'addAge', payload 也就是 10, 然后调用了 mutations 中的方法

报错的位置在这里,因为我在 commit 方法中,拿到了传递进来的 type,也就是 'addAge', 代码继续往下执行,执行到 this.mutations[type](payload); this 是 undefined,所以报错了。

正是因为在 actions 中的方法中,我调用了 commit 方法,也就是调用了 mutations 中的方法,在调用时没有告诉 commit 方法,this 是谁,所以才会报错。

那么怎么解决这个问题呢?其实很简单,只需要将之前的 commit 方法改为箭头函数即可,因为改为了箭头函数,this 就是当前 Store 实例了(改为了箭头函数当前在哪里定义的那么 this 就是谁),代码如下:

commit = (type, payload) => {
this.mutations[type](payload);
}

运行项目,测试结果如下:

到此为止,actions 的功能就实现了,接下来我们来回顾一下实现的思路。

  1. 将传递进来的 actions 放到 Store 上
  2. 在 Store 上添加 dispatch 方法
  3. 在 dispatch 方法中,调用 actions 中的方法
  4. 在 actions 中的方法中,调用 commit 方法
  5. 在 commit 方法中,调用 mutations 中的方法(这里就走我们上一篇章的流程了)

手撕Vuex-实现actions方法的更多相关文章

  1. 手撕RPC框架

    手撕RPC 使用Netty+Zookeeper+Spring实现简易的RPC框架.阅读本文需要有一些Netty使用基础. 服务信息在网络传输,需要讲服务类进行序列化,服务端使用Spring作为容器.服 ...

  2. NN入门,手把手教你用Numpy手撕NN(一)

    前言 这是一篇包含极少数学推导的NN入门文章 大概从今年4月份起就想着学一学NN,但是无奈平时时间不多,而且空闲时间都拿去做比赛或是看动漫去了,所以一拖再拖,直到这8月份才正式开始NN的学习. 这篇文 ...

  3. NN入门,手把手教你用Numpy手撕NN(2)

    这是一篇包含较少数学推导的NN入门文章 上篇文章中简单介绍了如何手撕一个NN,但其中仍有可以改进的地方,将在这篇文章中进行完善. 误差反向传播 之前的NN计算梯度是利用数值微分法,虽容易实现,但是计算 ...

  4. NN入门,手把手教你用Numpy手撕NN(三)

    NN入门,手把手教你用Numpy手撕NN(3) 这是一篇包含极少数学的CNN入门文章 上篇文章中简单介绍了NN的反向传播,并利用反向传播实现了一个简单的NN,在这篇文章中将介绍一下CNN. CNN C ...

  5. 编译原理--05 用C++手撕PL/0

    前言 目录 01 文法和语言.词法分析复习 02 自顶向下.自底向上的LR分析复习 03 语法制导翻译和中间代码生成复习 04 符号表.运行时存储组织和代码优化复习 05 用C++手撕PL/0 在之前 ...

  6. 用C/C++手撕CPlus语言的集成开发环境(1)—— 语言规范 + 词法分析器

    序言 之所以叫做CPlus语言,是因为原本是想起名为CMinus的,结果发现GitHub和Gitee上一堆的CMinus的编译器(想必都是开过编译原理课程并且写了个玩具级的语言编译器的大佬们吧).但是 ...

  7. 手撕spring核心源码,彻底搞懂spring流程

    引子 十几年前,刚工作不久的程序员还能过着很轻松的日子.记得那时候公司里有些开发和测试的女孩子,经常有问题解决不了的,不管什么领域的问题找到我,我都能帮她们解决.但是那时候我没有主动学习技术的意识,只 ...

  8. java实现二叉树的Node节点定义手撕8种遍历(一遍过)

    java实现二叉树的Node节点定义手撕8种遍历(一遍过) 用java的思想和程序从最基本的怎么将一个int型的数组变成Node树状结构说起,再到递归前序遍历,递归中序遍历,递归后序遍历,非递归前序遍 ...

  9. (面试题)面试官为啥总是让我们手撕call、apply、bind?

    引言 上一篇关于<面试官为啥总是喜欢问前端路由实现方式>的文章发布后,发现还是挺受欢迎的.这就给我造成了一定的困惑 之前花了很长时间,实现了一个自认为创意还不错的关于前端如何利用node+ ...

  10. Netty实现高性能IOT服务器(Groza)之手撕MQTT协议篇上

    前言 诞生及优势 MQTT由Andy Stanford-Clark(IBM)和Arlen Nipper(Eurotech,现为Cirrus Link)于1999年开发,用于监测穿越沙漠的石油管道.目标 ...

随机推荐

  1. [TSG开发日志4]算法组件、个人编写的库文件如何封装成DLL,如何更好地对接软件开发?

    写在前面 这个内容确实是我有点疏忽了,我以为做算法的同事应该多少对这方面会有点了解的.但是我想了一下我刚毕业的时候,确实对这方面的理解不深,查了很多资料才勉强搞懂什么意思,也是后来随着工程学习的愈加深 ...

  2. PTA 21级数据结构与算法实验4—字符串和数组

    目录 7-1 字符串模式匹配(KMP) 7-2 [模板]KMP字符串匹配 7-3 统计子串 7-4 好中缀 7-5 病毒变种 7-6 判断对称矩阵 7-7 三元组顺序表表示的稀疏矩阵转置运算Ⅰ 7-8 ...

  3. 青少年CTF-Web-CheckMe01

    题目描述 半颗星的简单题,CheckMe01 启动题目,并访问. 解题过程 访问题目页面,提示我们需要输入一个Key. 随便输入一个值,发现出现了一些代码. 我们仔细阅读代码,来了解这段代码是干什么的 ...

  4. 好用的css3特性-动画和3d变换

    上一篇文章总结了过渡和2D变化,这一篇来总结一下动画和3D变换,动画可用的场景也很多,比如在加载的页面的时候,可以放置一个gif图,也可以自定义小动画来缓解用户等待的焦虑感,比如以下三个小圆圈转圈圈的 ...

  5. 优化nginx参数(基本通用参数)

    全局域配置参数 worker_processes auto; worker_cpu_affinity auto; worker_rlimit_nofile 65530; 前两个参数用于开启nginx多 ...

  6. nginx搭建静态文件下载服务器

    配置文件大致内容 server { # 监听8001端口 listen 8001; server_name 192.168.0.2; # 指定使用utf8的编码 charset utf-8; # 内容 ...

  7. 关于 Llama 2 的一切资源,我们都帮你整理好了

    Llama 2 是一个由 Meta 开发的大型语言模型,是 LLaMA 1 的继任者.Llama 2 可通过 AWS.Hugging Face 获取,并可以自由用于研究和商业用途.Llama 2 预训 ...

  8. 一次Java内存占用高的排查案例,解释了我对内存问题的所有疑问

    原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,非公众号转载保留此声明. 问题现象 7月25号,我们一服务的内存占用较高,约13G,容器总内存16G,占用约85%,触发了内存报警(阈值8 ...

  9. 《Kali渗透基础》06. 主动信息收集(三)

    @ 目录 1:服务识别 1.1:NetCat 1.2:Socket 1.3:dmitry 1.4:nmap 2:操作系统识别 2.1:Scapy 2.2:nmap 2.3:p0f 3:SNMP 扫描 ...

  10. 如何获取和分析Java堆信息

    引言 在Java应用程序的开发和维护过程中,了解和分析Java堆信息是一项重要的任务.本文将介绍如何获取Java堆信息的不同方法,并提供一些分析堆信息的实用技巧. 获取Java堆信息的方法 Java虚 ...