一,前言
上一篇,主要介绍了 Vuex 中 Mutations 和 Actions 的实现,主要涉及以下几个点:
至此,一个简易版的 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 模块安装的实现;
评论