首页 > 其他分享 >手撕Vuex-模块化共享数据上

手撕Vuex-模块化共享数据上

时间:2024-01-05 12:05:08浏览次数:28  
标签:name 模块化 getters state 模块 共享 Vuex store


前言

好,经过上一篇的介绍,实现了 Vuex 当中的 actions 方法,接下来我们来实现 Vuex 当中的模块化共享数据(modules)。

modules 方法用于模块化共享数据,那么什么叫模块化共享数据呢?其实非常简单。

过去我们将所有模块的数据都放到 state 中共享,例如:

我们有三个模块 首页 / 个人中心 / 登录,那么我们就会将这三个模块的数据都放到 state 中,但是这样会导致命名匮乏的问题。

比如说首页中需要共享name, 个人中心中也需要共享name / 登录中也需要共享name,并且这三个name的取值还不一样, 那么为了能把这三条数据放到同一个state中, 我们就必须指定不同的名称, 例如:

state:{
    homeName: 'www',
    accountName: 'BNTang',
    loginName: 'top'
}

这样就会导致命名匮乏的问题,而且如果我们的项目足够大,那么我们的 state 中就会有很多的数据,这样就会导致我们的 state 中的数据非常多,而且不好管理。

为了解决这个问题,Vuex 就推出了模块化共享数据的方法,那么什么叫模块化共享数据呢?模块化共享数据就是将不同模块的数据放到不同的模块(state)中,这个就是模块化共享数据。

那么模块化共享数据怎么做呢,我们先不要管怎么做,我们先来看看模块化共享数据的好处。

我们还是拿上面的例子来说,我们有三个模块 首页 / 个人中心 / 登录,那么我们就会将这三个模块的数据都放到 state 中,但是这样会导致命名匮乏的问题。

好,到这里我们已经知道了模块化共享数据的好处,我们先来用一下模块化共享数据。

我先不管三七二十一,我在 Store 对象的 store 中定义了一个全局的数据 globalName 取值为 BNTang,

定义完毕之后呢,这个 globalName 代表着全局的数据,那么我们就可以在任何一个模块当中使用这个数据,那么接下来怎么办,例如这个时候我有两个模块分别是首页与个人中心,这两个模块中分别有一个 name 数据,这两个 name 该如何做呢,好我先写代码再来解释。

let home = {
    state: {
        name: '首页'
    },
    getters: {},
    mutations: {},
    actions: {}
}

如上的代码和 Store 中有一套相同的结构,这个对象中保存着首页的 name,保存完毕了之后,还没添加到 Store 中,那么如何添加到 Store 中呢,其实很简单,我们只需要在 Store 中的 modules 中添加这个模块就可以了。

modules: {
    home: home
}

如上代码的写法就代表着,我们 Store 除了保存了全局的共享数据以外还保存了首页模块的共享数据,那么我们的个人中心数据该如何做呢,其实也是一样的(也是同一个世界,同一个梦想的),我们来写一个个人中心的模块。

let account = {
    state: {
        name: '账户'
    },
    getters: {},
    mutations: {},
    actions: {}
}

然后将这个模块添加到 Store 中,方式和上面一样。

modules: {
    home: home,
    account: account
}

好了,到这里我们已经定义了全局共享的数据,与各个模块的共享数据,我们保存归保存,但是我们怎么使用呢,我们来看看。

拿全局共享的数据(随机找一个组件展示数据即可):

<p>{{ this.$store.state.globalName }}</p>

拿首页的共享数据(随机找一个组件展示数据即可):

<p>{{ this.$store.state.home.name }}</p>

拿个人中心的共享数据(随机找一个组件展示数据即可):

<p>{{ this.$store.state.account.name }}</p>

测试效果我不贴图了本人亲自测试过,有个 注意点,我们的 Nuex 还没有实现模块化,所以在测试的时候记得将自己实现的 Nuex 注释掉,打开官方的 Vuex。

到这里,我们的页面就已经展示了全局共享数据与模块化共享数据,完成了将不同模块的数据放到不同的模块(state)中,这个就是模块化共享数据。

模块化中 getters/mutations/actions 的使用

我们知道在 Store 当中,我们可以使用 getters/mutations/actions 这三个方法,那么这三个方法在模块化当中是怎么使用的呢,先看全局的,在全局 Store 分别在这三个方法中定义方法,如下:

getters: {
    getGlobalName(state) {
        return state.globalName + '111111';
    }
},
mutations: {
    changeGlobalName(state, payload) {
        state.globalName += payload;
    }
},
actions: {
    asyncChangeGlobalName({commit}, payload) {
        setTimeout(() => {
            commit('changeGlobalName', payload);
        }, 1000);
    }
},

内容非常的简单,如果是从之前的文章一步一步跟着来的再看如上的代码基本上没有什么压力(我这里不做过多的解释,因为前面讲解的很细,不懂的可以回去翻看之前章节的介绍),然后我们在组件当中使用这三个方法,如下:

<template>
  <div class="hello">
    <p>{{ this.$store.state.globalName }}</p>
    <p>{{ this.$store.getters.getGlobalName }}</p>
    <button @click="globalFn1">同步操作</button>
    <button @click="globalFn2">异步操作</button>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  methods: {
    globalFn1() {
      this.$store.commit('changeGlobalName', 10);
    },
    globalFn2() {
      this.$store.dispatch('asyncChangeGlobalName', 5);
    }
  }
}
</script>
<style scoped>
</style>

关于测试自行测试,这里不做过多的解释(运行项目,点击页面上面的按钮即可查询效果)。

好了这里我们已经知道了全局的 getters/mutations/actions 的使用,那么模块化当中的 getters/mutations/actions 的使用又是怎么样的呢,我们来看看。

我先不管三七二十一,我在 home 模块中的 getters/mutations/actions 中定义方法,如下:

首页模块:

getters: {
    getHomeName(state) {
        return state.name + '222222';
    }
},
mutations: {
    changeHomeName(state, payload) {
        state.name += payload;
    }
},
actions: {
    asyncChangeHomeName({commit}, payload) {
        setTimeout(() => {
            commit('changeHomeName', payload);
        }, 1000);
    }
}

我这个时候想,我在全局 Store 的 getters/mutations/actions 方法中定义了方法,可以和之前的方式一样使用,那么在模块中的 getters/mutations/actions 方法中定义了方法,我能不能和之前的方式一样使用呢,我们来看看。

首先展示首页模块中的 name, 如果这里直接和之前一样的写法肯定是不能展示的,所以这里我就要提到一个注意点:如果获取的是模块中state共享的数据, 那么需要加上模块的名称

知道了这个注意点之后,我们的代码就可以改写为如下的方式来展示模块中 store 存储的数据,代码如下:

<p>{{ this.$store.state.home.name }}</p>

手撕Vuex-模块化共享数据上_javascript

上面这一点是我们在使用模块化共享数据的时候需要注意的,与寻常的使用方式不同,需要加上模块的名称。

那么我们从 getters/mutations/actions 中获取数据呢,如果获取的是模块中getters共享的数据, 那么不需要加上模块的名称,代码如下:

<p>{{ this.$store.getters.getHomeName }}</p>

手撕Vuex-模块化共享数据上_前端_02

mutation 与 action 与使用全局的方式一样,不需要加上模块的名称, 在页面编写两个按钮,一个是同步,一个是异步,在分别实现下各个按钮的点击事件即可, 代码如下:

添加按钮:

<button @click="homeFn1">同步操作</button>
<button @click="homeFn2">异步操作</button>

实现方法:

homeFn1() {
  this.$store.commit('changeHomeName', 10);
},
homeFn2() {
  this.$store.dispatch('asyncChangeHomeName', 5);
}

好了,我们首页模块的 getters/mutations/actions 的使用代码编写好了,我们赶紧趁热来测试一下,看看我们的代码是否能够正常的运行,打开浏览器点击按钮即可完成测试我这里略过。

首页模块的我们编写完毕了,接着来编写个人中心模块的 getters/mutations/actions 的使用,其实和首页模块的 getters/mutations/actions 的使用是一样的,我们来看看,为了节约时间,我直接贴代码:

个人中心模块:

let account = {
    state: {
        name: '账户'
    },
    getters: {
        getAccountName(state) {
            return state.name + '333333';
        }
    },
    mutations: {
        changeAccountName(state, payload) {
            state.name += payload;
        }
    },
    actions: {
        asyncChangeAccountName({commit}, payload) {
            setTimeout(() => {
                commit('changeAccountName', payload);
            }, 1000);
        }
    }
}

页面展示:

<p>{{ this.$store.state.account.name }}</p>
<p>{{ this.$store.getters.getAccountName }}</p>
<button @click="accountFn1">同步操作</button>
<button @click="accountFn2">异步操作</button>

实现方法:

accountFn1() {
  this.$store.commit('changeAccountName', 10);
},
accountFn2() {
  this.$store.dispatch('asyncChangeAccountName', 5);
}

好了,到这里我们的模块化当中的 getters/mutations/actions 的使用就已经完成了。

其实除了在全局的 Store 中添加子模块,子模块还可以添加模块,可以无限的这样添加模块,例如我现在有一个登陆模块,我将登陆模块添加到 account 模块中,登陆模块的代码如下:

let login = {
    state: {
        name: '登录'
    },
    getters: {
        getLoginName(state) {
            return state.name + '333333';
        }
    },
    mutations: {
        changeLoginName(state, payload) {
            state.name += payload;
        }
    },
    actions: {
        asyncChangeLoginName({commit}, payload) {
            setTimeout(() => {
                commit('changeLoginName', payload);
            }, 1000);
        }
    }
}

然后将登陆模块添加到 account 模块中,代码如下:

modules: {
    login: login
}

手撕Vuex-模块化共享数据上_linux_03

然后我们在页面中展示登陆模块的数据,代码如下:

<p>{{ this.$store.state.account.login.name }}</p>
<p>{{ this.$store.getters.getLoginName }}</p>

展示数据的注意点与之前一样,需要加上模块的名称,而 getters 就不需要加上模块的名称,然后我们在页面中调用登陆模块的 mutations/actions 的方法,代码如下:

首先是触发按钮:

<button @click="loginFn1">同步操作</button>
<button @click="loginFn2">异步操作</button>

然后是实现方法:

loginFn1() {
  this.$store.commit('changeLoginName', 10);
},
loginFn2() {
  this.$store.dispatch('asyncChangeLoginName', 5);
}

好了,到这里我们的模块化的使用就已经完成了,我们赶紧来测试一下,看看我们的代码是否能够正常的运行,打开浏览器点击按钮即可完成测试我这里略过。

标签:name,模块化,getters,state,模块,共享,Vuex,store
From: https://blog.51cto.com/u_15652665/9112427

相关文章

  • 手撕Vuex-实现actions方法
    经过上一篇章介绍,完成了实现mutations的功能,那么接下来本篇将会实现actions的功能。本篇我先介绍一下actions的作用,然后再介绍一下实现的思路,最后再实现代码。actions的作用是用来异步修改共享数据的,怎么异步修改,这个时候我们回到Vue的官方Vuex文档中,有如下这么一个图:从......
  • 手撕Vuex-实现mutations方法
    经过上一篇章介绍,完成了实现getters的功能,那么接下来本篇将会实现mutations的功能。在实现之前我们先来回顾一下mutations的使用。将官方的Vuex导入进来,因为我们的还没有实现,现用一下官方的,来演示一下mutations的使用。mutations是用来修改共享数据的,先在mutations中......
  • 手撕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......