首页 > 其他分享 >手撕Vuex-实现actions方法

手撕Vuex-实现actions方法

时间:2023-11-01 23:56:56浏览次数:34  
标签:调用 Vuex mutations actions commit 方法 payload

经过上一篇章介绍,完成了实现 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,mutations,actions,commit,方法,payload
From: https://www.cnblogs.com/BNTang/p/17804438.html

相关文章

  • 有什么可以自动保存微信收到的图片和视频的方法么
    8-1在一些有外勤工作的公司里,经常会需要在外面工作的同事把工作情况的图片发到指定微信或者指定的微信群里,以记录工作进展等,或者打卡等,对于外勤人员来说,也就发个图片的事,但是对于在公司里收图片的人来说,可能是个麻烦的活。因为有可能每天要保存上千张图片,或者视频,要是都靠人工保存......
  • 一次彻底卸载Anaconda的简便方法
    在计算机上使用Anaconda作为Python环境管理工具是一种常见的选择,但随着时间的推移,可能会遇到需要重新安装或升级Anaconda的情况。然而,彻底卸载Anaconda并不总是一件容易的事情,尤其是在旧版本上。在本文中,我将分享一种简便而可行的方法,以确保Anaconda被完全卸载,以便进行新的安装或......
  • android ebpf之uprobe原理和检测方法
    uprobe通过内核层对用户层进程的指定地址的原指令copy到其他位置,然后写入指定类型中断指令,然后内核中设置对应的中断处理程序,中断处理程序中执行uprobe设置的回调过滤函数,然后设置单步执行copy的原指令后恢复寄存器状态继续执行。ida查看被uprobehook的函数头部,指令被修改为了中断......
  • 矢量图输出、修订、以及插入方法——Matlab,PPT输出、Tex,Word输入
    矢量图输出、修订、以及插入方法1       输出图片1.1     MATLAB出图另存为pdf(tex中使用)或emf(word中使用)格式,svg格式不行,会导致图片失真1.2     PPT出图直接导出pdf或选中图片右键导出为svg(这样就不用去白边)1.3     Python出图python的matplotli......
  • 电商商品价格数据接口的具体方法和应用效果
    电商商品价格数据接口的具体方法包括以下步骤:获取API密钥:在使用任何API之前,需要获取一个API密钥,用于验证身份和确保请求安全。调用API:根据电商平台提供的API文档,使用合适的编程语言(如Python、Java、JavaScript等)调用API。通常需要提供一些参数(如商品ID、价格阈值等),然后API会返回所......
  • 简便有效的去除照片上的水印方法教您如何去除水印!
    许多网友都在寻找方法去除照片上的水印,水印通常用于保护版权或标识来源,但有时候我们可能需要使用带有水印的照片,却又不希望水印影响观感,今天我将向大家介绍两种有效的方法,帮助解决“如何去除照片上的水印”这一难题,让您轻松处理照片。一、水印云-去除照片上的水印水印云是一款快......
  • 三种简单实用的方法帮助你去除抖音视频上的水印
    如今越来越多的人涉足自媒体工作,在这个过程中,我们经常会遇到一个普遍的问题在寻找素材时,发现视频上带有抖音的水印,这些水印可能会对我们的创作产生负面影响,不过别担心!我将与你分享三种简单实用的方法,帮助你抖音视频去水印。第一种方法、水印云水印云是一款快速去水印的软件可以帮你......
  • 应用出现闪退的原因和解决方法
    大家好,我是咕噜-凯撒,相信很多人也遇到过打开一个应用突然卡了一下然后应用直接关闭并且返回到了主屏幕,这个问题不仅让用户感到很烦,还有可能会导致数据丢失和工作中断,哪都有哪些原因又都有哪些解决的方法,我以自己的了解总结了几点。                ......
  • 如何在Vue组件中访问Vuex store中的状态?
    在Vue组件中访问Vuexstore中的状态,可以通过计算属性(computedproperties)或者直接通过$store.state来实现。下面是两种常见的方法:1:使用计算属性(computedproperties):在Vue组件中,定义一个计算属性来获取Vuexstore中的状态。计算属性会根据状态的变化自动更新。exportdefaul......
  • App渗透测试有哪些测试方法?可进行移动app测试的公司推荐
    App渗透测试是当前互联网时代中不可或缺的重要环节。随着智能手机的普及和App应用的广泛使用,App渗透测试帮助企业保障其移动应用的安全性和可靠性,确保用户的隐私和敏感信息不会被黑客窃取。那么,什么是App渗透测试呢?它有哪些测试方法?接下来,我们将为您一一详细解答。App渗......