• 手撕Vuex-实现mutations方法


    经过上一篇章介绍,完成了实现 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 组件中进行展示的:

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

    在 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 就处理完毕了。


    __EOF__

  • 本文作者: BNTang
  • 本文链接: https://www.cnblogs.com/BNTang/p/17801892.html
  • 关于博主: 评论和私信会在第一时间回复。或者直接私信我。
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
  • 声援博主: 如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。
  • 相关阅读:
    Kubernetes Node Not Ready Error
    三分钟学习一个python小知识8-----------我的对python中pandas的理解--补充,
    SpringCloud Alibaba&注册中心(nacos)&远程调用(OpenFeign)使用
    在 Ubuntu 环境中安装 Go 语言及运行脚本
    解决AU报“MME无法使用“问题
    GCC Rust获批将被纳入主线代码库,或将于GCC 13中与大家见面
    中标麒麟Linux64平台上QT5.6.3源码编译安装
    Leetcode 刷题日记 剑指 Offer II 055. 二叉搜索树迭代器
    大数据与Hadoop入门理论
    Python搭配GBase 8s
  • 原文地址:https://www.cnblogs.com/BNTang/p/17801892.html