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

手撕Vuex-实现mutations方法

时间:2024-01-05 12:04:44浏览次数:28  
标签:Vuex getters mutations options state 方法 payload


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

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

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

手撕Vuex-实现mutations方法_javascript

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

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

手撕Vuex-实现mutations方法_javascript_02

在 state 当中定义 num:

手撕Vuex-实现mutations方法_服务器_03

接下来就是使用了,使用的时候需要使用 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>

手撕Vuex-实现mutations方法_前端_04

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

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

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

手撕Vuex-实现mutations方法_java_05

这个就是 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-实现mutations方法_算法_06

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

手撕Vuex-实现mutations方法_服务器_07

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

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

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

代码如下:

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

手撕Vuex-实现mutations方法_算法_08

实现了 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);

手撕Vuex-实现mutations方法_前端_09

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

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

标签:Vuex,getters,mutations,options,state,方法,payload
From: https://blog.51cto.com/u_15652665/9112430

相关文章

  • 手撕Vuex-实现共享数据
    经过上一篇章介绍,完成了添加全局$store,接下来就是实现共享数据的功能。在Vuex中,共享数据是通过state来实现的,所以我们需要在Nuex.js文件中实现state的功能。在Vuex中,state是一个对象,这个对象中存放的就是我们的共享数据,所以我们需要在Nuex.js文件中定义一个state对......
  • 手撕Vuex-实现getters方法
    经上一篇章介绍,完成了实现共享数据的功能,实现方式是在Store构造函数中将创建Store时将需要共享的数据添加到Store上面,这样将来我们就能通过this.$store拿到这个Store,既然能拿到这个Store,我们就可以通过.state拿到需要共享的属性。除了可以通过.state拿到共享数据之外......
  • 手撕Vuex-添加全局$store
    经过上一篇的介绍,了解到了Vuex的实现本质就是一个插件,所以要做的事情就是实现这个插件的代码编写即可。本篇文章主要是实现一个全局的$store,这个$store是挂载在Vue的原型上的,所以在任何一个组件当中都可以通过this.$store访问到。我们先来看看Vue官方的,我们分别在App.v......
  • 手撕Vuex-Vuex实现原理分析
    本章节主要围绕着手撕Vuex,那么在手撕之前,先来回顾一下Vuex的基本使用。创建一个Vuex项目,我这里采用vue-cli创建一个项目,然后安装Vuex。vuecreatevuex-demo选择Manuallyselectfeatures。这里只需要,Babel与Vuex。选择2.X版本的Vue:创建package.json:是否保存为模板......
  • 手撕Vuex-模块化共享数据下
    前言好,经过上一篇的介绍,了解了Vuex当中的模块化,本章主要介绍Vuex当中的模块化共享数据下篇。我们知道在全局的Store对象当中,我们可以定义全局的数据,那么如果我们在模块当中也定义了一个属性名称和全局的属性名称相同,那么会发生什么呢?我们先来看看,在全局当中定义了一个global......
  • 手撕Vuex-提取模块信息
    前言在上一篇【手撕Vuex-模块化共享数据】文章中,已经了解了模块化,与共享数据的注意点。那么接下来就要在我们自己的Nuex中实现共享数据模块化的功能。那么怎么在我们自己的Nuex中实现共享数据模块化的功能呢?处理数据也非常的简单,是不是就是处理一下子模块的数据,处理一下子模块......
  • 手撕Vuex-安装模块数据
    前言根据上一篇,【手写Vuex】-提取模块信息,我们已经可以获取到模块的信息了,将模块信息变成了我们想要的数据结构,接下来我们就要根据模块的信息,来安装模块的数据。在上一篇当中我们定义了一个ModuleCollection类,这个类的作用就是将模块的信息转换成我们想要的数据结构。接下来我们......
  • 手撕Vuex-安装模块方法
    前言经过上一篇文章的介绍,我们实现了将模块安装到store中,那么本章我们就来介绍一下怎么安装模块当中的方法也就是actions、mutations、getters。所以本次文章的目标就是将模块当中的actions、mutations、getters安装到store中,然后在组件中使用。分析阶段那么安装actions、m......
  • Dart 非常详细日期的操作方法
    Dart非常详细日期的操作方法近期在研究Dart源码,把关于Date这一块写个文章进行整理分享。在Dart中操作日期通过DateTime类来实现。由于DateTime是Dart内置的,所以不需要导入。解析DateTimeDateTime.parseDateTime.tryParseDateTime.utc解析一个日期可以通过DateTime.p......
  • 探索架构之美 | 小米分享架构师的方法论
    大家好,我是小米!今天我们要聊的话题可是相当精彩——“架构师的方法论”!作为一名热爱技术的小伙伴,我深知在软件开发领域,拥有一套科学的方法论是多么的重要。所以,不废话,让我们一起踏上探索架构的奇妙世界的征程吧!第一章:架构师的身份认同作为架构师,我们首先要明确自己的身份。不仅仅是......