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

在实现之前我们先来回顾一下 mutations 的使用。

将官方的 Vuex 导入进来,因为我们的还没有实现,现用一下官方的,来演示一下 mutations 的使用。

mutations 是用来修改共享数据的,先在 mutations 中定义一个方法,这个方法接受两个参数,第一个参数是 state,第二个参数是 payload,payload 是一个对象,这个对象中存放的是我们需要修改的数据。

addNum(state, payload) {
state.num += payload;
},

在 state 当中定义 num:

接下来就是使用了,使用的时候需要使用 commit 方法,commit 方法接受两个参数,第一个参数是方法名,第二个参数是 payload,payload 是一个对象,这个对象中存放的是我们需要修改的数据。

随便找一个组件,先展示我们的 num,然后在编写一个按钮,点击按钮之后调用 addNum 方法,传入一个参数 10,这样就可以实现 num 的增加了。

展示 num,我这里在 HelloWorld.vue 组件中进行展示的:

<template>
<div class="hello">
<p>{{ this.$store.state.num }}</p>
</div>
</template>

展示完毕之后在编写一个按钮,点击按钮之后调用 addNum 方法:

<button @click="myFn">我是按钮</button>

在 HelloWorld.vue 组件中编写 myFn 方法:

myFn() {
this.$store.commit('addNum', 10);
},

好了到这里,我们的基本结构搭建完毕,运行一下,看看效果:

这个就是 mutations 的基本使用,那么了解完和回顾完毕之后,接下来我们就来实现 mutations 的功能。

其实 mutations 的实现和 getters 的实现差不多,好,我们废话不多说,直接来处理下吧,我先将上一篇处理 getters 的代码封装下,然后再来处理 mutations 的代码。

我单独抽取一个 initGetters 来做这个事情,这样代码就清晰了很多,这个 initGetters 方法接受一个 options,然后在将之前处理的代码放进去即可。

代码如下:

constructor(options) {
this.state = options.state;
// 将传递进来的 getters 放到 Store 上
this.initGetters(options);
} initGetters(options) {
// 1.拿到传递进来的getters
let getters = options.getters || {};
// 2.在Store上新增一个getters的属性
this.getters = {};
// 3.将传递进来的getters中的方法添加到当前Store的getters上
for (let key in getters) {
Object.defineProperty(this.getters, key, {
get: () => {
// 4.将getters中的方法执行, 并且将state传递过去
return getters[key](this.state);
}
})
}
}

这样我们的 getters 就处理完毕了,接下来我们就来处理 mutations 的代码。

一样的我编写一个 initMutations 方法,这个方法接受一个 options, 这里的步骤和 getters 的步骤是一样的,我们先来看一下代码:

initMutations(options) {
// 1.拿到传递进来的mutations
let mutations = options.mutations || {};
// 2.在Store上新增一个mutations的属性
this.mutations = {};
// 3.将传递进来的mutations中的方法添加到当前Store的mutations上
for (let key in mutations) {
this.mutations[key] = (payload) => {
mutations[key](this.state, payload);
}
}
}

这样 Store 上面就有了一个 mutations 的属性,这个属性中存放的是我们传递进来的 mutations 方法,先来验证一下,打开浏览器,看看效果:

注意点:记得将官方的 Vuex 注释掉,用我们自己的 Nuex。

这样我们的 mutations 就处理完毕了,接下来我们就来处理一下 commit 方法。

通过之前我们在使用 mutations 的时候,是通过 store.commit 方法来调用的,所以我们需要在 Store 上面添加一个 commit 方法,这个方法接受两个参数,第一个参数是方法名,第二个参数是 payload,payload 是一个对象,这个对象中存放的是我们需要修改的数据。

commit 方法具体的实现代码逻辑就是去 mutations 中找到对应的方法,然后执行这个方法,将 state 和 payload 传递过去。

代码如下:

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

实现了 commit 方法之后,我们就可以在组件中使用了,我们先来验证一下,打开浏览器,看看效果:

我这里不截图了,效果就是点击了按钮发现 num 值并没有发生变化,这是为什么呢?

因为我们在 mutations 中修改的是 state 当中的数据,state 并没有实现双向绑定,所以不改变是正常的。

那么在 mutations 中更改了 state 的数据之后,我们怎么去更新视图呢?这里我们只需要将 state 变成双向绑定的即可,这里我们使用 Vue 当中的 util 工具类来进行快速实现双向绑定。

正好呢通过这个问题,可以让大家知道在 Vue 中的 util 工具类中提供了有一个方法叫做 defineReactive,这个方法可以让我们的数据变成双向绑定的。

通过这个方法就可以快速的将某个数据变成双向绑定的数据,defineReactive 这个方法接收三个参数:

  • 第一个参数: 要给哪个对象添加属性
  • 第二个参数: 要给指定的对象添加什么属性
  • 第三个参数: 要给这个属性添加什么值

好了,废话不多说,我们直接来处理一下吧,我们先导入 Vue,就可以通过 Vue.util.defineReactive 来调用这个方法了。

代码如下:

Vue.util.defineReactive(this, 'state', options.state);

本章的重点就是要知道在 Vue 当中有 defineReactive 方法,这个方法可以让我们的数据变成双向绑定的,这样我们就可以在 mutations 中修改 state 的数据之后,视图也会发生变化了。

这样我们的 state 就变成了双向绑定的了,验证一下,打开浏览器,看看效果即可,好了到这里,我们的 mutations 就处理完毕了。

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

  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. PerfView专题 (第十五篇): 如何洞察 C# 中的慢速方法

    一:背景 1. 讲故事 在 dump 分析旅程中,经常会遇到很多朋友反馈一类问题,比如: 方法平时都执行的特别快,但有时候会特别慢,怎么排查? 我的方法第一次执行特别慢,能看到慢在哪里吗? 相信有朋友 ...

  2. nrm工具

    nrm 工具 nrm(npm registry manager)是npm镜像源管理工具.可快速帮助查看.切换.管理npm镜像源. 安装 npm install -g nrm 查看 nrm ls 切换 ...

  3. golang技术降本增效的手段

    最近一年各大中小厂都在搞"优化",说到优化,目的还是"降本增效",降低成本,增加效益(效率). 技术层面,也有一些降本增效的常规操作. 比如池化.io缓冲区技术 ...

  4. React: husky > pre-push hook failed (add --no-verify to bypass)

    解决方案 提交commit和推送代码时都加上--no-verify参数,然他跳过检查 提交 推送

  5. Pycharm:显示每一行代码的修改记录

    解决方案 安装插件GitToolBox

  6. 【教程】AWD中如何通过Python批量快速管理服务器?

    前言 很多同学都知道,我们常见的CTF赛事除了解题赛之外,还有一种赛制叫AWD赛制.在这种赛制下,我们战队会拿到一个或多个服务器.服务器的连接方式通常是SSH链接,并且可能一个战队可能会同时有多个服务 ...

  7. [ABC128E] Roadwork

    2023-01-14 题目 题目传送门 翻译 翻译 难度&重要性(1~10):4 题目来源 AtCoder 题目算法 区间覆盖,线段树,双堆 解题思路 可以将问题转化为区间覆盖问题和单点查询问 ...

  8. java学习阶段一

    扩展名默认没有打开 FIRST APP public class HelloWorld { public static void main (String[] args){ System.out.pr ...

  9. 在 Spring 6 中使用虚拟线程

    一.简介 在这个简短的教程中,我们将了解如何在 Spring Boot 应用程序中利用虚拟线程的强大功能. 虚拟线程是Java 19 的预览功能,这意味着它们将在未来 12 个月内包含在官方 JDK ...

  10. redhat7查找已接网线但是还未配置IP的网卡接口

    方法一:nmcli 输出中参数WIRED-PROPERTIES.CARRIER为on即为接网线网卡 #nmcli device show |grep -i -E "device|carrie ...