写点什么

【Vuex 源码学习】第六篇 - Vuex 的模块收集

用户头像
Brave
关注
发布于: 1 小时前
【Vuex 源码学习】第六篇 - Vuex 的模块收集

一,前言


上一篇,主要介绍了 Vuex 中 Mutations 和 Actions 的实现,主要涉及以下几个点:


  • 将 options 选项中定义的 mutation 方法绑定到 store 实例的 mutations 对象;

  • 创建并实现 commit 方法;

  • 将 options 选项中定义的 action 方法绑定到 store 实例的 actions 对象;

  • 创建并实现 dispatch 方法;


至此,一个简易版的 Vuex 状态管理插件就完成了;


本篇,继续介绍 Vuex 中模块相关概念,模块收集部分;


二,Vuex 模块的概念


前面分别介绍了 vuex 中 state、getters、mutations、actions 的实现;


当项目非常庞大时,state、getters、mutations、actions 中就会包含大量的内容;


此时,我们希望为这些状态划分独立的模块(即作用域);


在每个独立的模块下,都有属于它自己的功能:state、getters、mutations、actions;


并且这些模块可以拆分为单独的文件,分别进行代码维护;


模块的定义时序使用到 Vuex 的 modules;


加载时,会将 modules 中声明的 vuex 模块,与主模块进行合并;


当多个模块中存在相同名称的状态时,默认会同时变化,可添加 namespaced 命名空间进行隔离;


vuex 的模块,理论上是支持无限层级递归的;


---

三,Vuex 模块的使用


基于前面的代码,为了完整的测试 vuex 的 modules 模块与 namespaced 命名空间;


仿造当前 Demo,再创建 2 个相似的模块 moduleA 和 moduleB:


模块 A:moduleA

// src/store/moduleA
export default { state: { num: 20 }, getters: { }, mutations: { changeNum(state, payload) { state.num += payload; } }, actions: { }};
复制代码


模块 B:moduleB

// src/store/moduleB
export default { state: { num: 30 }, getters: { }, mutations: { changeNum(state, payload) { state.num += payload; } }, actions: { }};
复制代码


在 src/store/index.js 中,引入并注册两个模块 moduleA 和 moduleB:

// src/store/index.js
import Vue from 'vue';import Vuex from 'vuex'; // 使用 vuex 官方插件
// 引入两个测试模块import moduleA from './moduleA'import moduleB from './moduleB'
Vue.use(Vuex);
const store = new Vuex.Store({ state: { //... }, getters: { //... }, mutations: { //... }, actions: { //... }, modules:{ moduleA, moduleB }});export default store;
复制代码


在 src/App.vue 中,添加模块方法的调用:

// src/App.vue
<template> <div id="app"> 商品数量: {{this.$store.state.num}} 个<br> 商品单价: 10 元<br> 订单金额: {{this.$store.getters.getPrice}} 元<br> <button @click="$store.commit('changeNum',5)">同步更新:数量+5</button> <button @click="$store.dispatch('changeNum',-5)">异步更新:数量-5</button> <!-- 测试 State 数据响应式 --> <button @click="$store.state.num = 100">测试 State 数据响应式</button>
<br> 模块测试: <br> A 模块-商品数量: {{this.$store.state.moduleA.num}} 个<br> B 模块-商品数量: {{this.$store.state.moduleB.num}} 个<br> </div></template>
复制代码

npm run serve启动服务,测试模块状态取值:


问题:

由于 demo 的特殊性,多个模块存在相同名称的属性:商品数量 num

此时,当进行数据更新时,这些同名属性会同时触发改变;


测试:点击同步更新按钮

主模块和 A、B 两个模块中共三个 num 状态同时发生改变;


虽然划分了模块,但模块之间还不是独立关系,

模块合并时,相当于将多个模块中的相同状态合并为数组,触发时都会被执行;


vuex 的命名空间:

如果想要严格划分一个空间,需要添加命名空间:

// src/store/moduleA
export default { namespaced: true, state: { num: 20 }, getters: { }, mutations: { changeNum(state, payload) { state.num += payload; } }, actions: { }};
复制代码


添加了 namespaced 命名空间后,再点击更新按钮,模块中的状态不会发生改变:


这时,触发对应模块的数据更新需要添加模块的命名空间标识:

<template>  <div id="app">    <br> 模块测试: <br>    A 模块-商品数量: {{this.$store.state.moduleA.num}} 个<br>    B 模块-商品数量: {{this.$store.state.moduleB.num}} 个<br>    <button @click="$store.commit('moduleA/changeNum',5)">A 模块-同步更新:数量+5</button>    <button @click="$store.commit('moduleB/changeNum',5)">B 模块-同步更新:数量+5</button>  </div></template>
复制代码

测试效果



四,Vuex 模块收集的实现


头疼中,明日完善;


五,结尾


本篇,主要介绍了 vuex 模块收集是如何实现的,主要包括以下几点:


  • Vuex 模块的概念;

  • Vuex 模块的使用;

  • Vuex 模块收集的实现;


下一篇,继续介绍 Vuex 模块安装的实现;


用户头像

Brave

关注

还未添加个人签名 2018.12.13 加入

还未添加个人简介

评论

发布
暂无评论
【Vuex 源码学习】第六篇 - Vuex 的模块收集