vuex 深层学习modules
文章目录
前言
首先,回顾一下vuex的核心概念(个人理解,方便记忆理解):
- state: 共享的数据
- mutations:同步操作,修改state数据的唯一方法 第一个形参是state数据 第二个形参是外面传入的数据
- actions:存储修改,异步操作 第一个参数表示上下文对象,第二个表示外部传入的数据
- getters:类似于计算属性,不允许修改 ,对state数据进行包装加工处理
- modules:模块化(也就是今天学习的内容)
提示:以下是本篇文章正文内容,下面案例可供参考
一、modules是什么?
- 官方介绍:modules,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理;如果所有的状态或者方法都写在一个store里面,将会变得非常臃肿,难以维护。
- 个人理解:为了让状态管理变得清晰,容易维护,适用于比较复杂的大型项目。可以拥有属于自己的state、mutation、action、getters、modules 互不影响。
这个图很重要 一定要记住哟!!!
二、如何实现模块化
1.创建
modules里面的state可以是函数,可以拥有这些自己的state、mutation、action、getters、modules
export default new Vuex.Store({
state: {
},
getters:{
},
mutations: {
},
actions: {
},
modules: {
模块名1:{
state:()=>({
}),
getters:{
},
mutations:{
},
actions:{
},
modules:{
}
},
模块名2:{
state:()=>({
}),
getters:{
},
mutations:{
},
actions:{
},
modules:{
}
}
}
})
这样写全部都在store/index.js里面难以维护,所以进行文件的抽离
模块1.js
export default ({
state: {
},
getters:{
},
mutations: {
},
actions: {
},
modules:{
}
}
})
index.js 中导入模块
import 模块1 from './modules/模块1';
import 模块2 from './modules/模块2';
export default new Vuex.Store({
state: {
},
getters:{
},
mutations: {
},
actions: {
},
modules: {
模块名1,
模块名2
}
})
2. 获取模块数据 调用模块方法
2.1 模块state
方法1:{
{
$store.state.模块名.属性名 }}
方法2:import {
mapState } from 'vuex';
computed:{
// 注意:对象写法
...mapState({
属性名:state=>state.模块名.属性名
})
}
2.2 模块getters
方法1:{
{
$store.getters.属性名 }}
方法2:import {
mapGetters } from 'vuex'
computed:{
...mapGetters(['属性名'])
}
2.3 模块mutations
方法1:$store.commit('方法名',实参)
方法2:import {
mapMutations } from 'vuex'
methods:{
...mapMutations(['方法名'])
}
2.4 模块actions
方法1:$store.dispatch('方法名',实参)
方法2:import {
mapActions} from 'vuex'
methods:{
...mapActions(['方法名'])
}
学到这,大家有没有发现,除了state模块有区别,其他的获取和出发没什么区别,那么问题来了,
如果模块化下的属性名和方法名,与根模块下的重复则会出现问题报错之类的,所以我们使用 命名空间来实现具体的模块化操作
3.开启命名空间(namespaced)
export default ({
state: {
},
getters:{
},
mutations: {
},
actions: {
},
modules:{
},
namespaced:true // 默认为false
}
})
在获取模块数据 调用模块方法的时候 一定要注意是哪个模块下面的属性名称
3.1 命名空间下的state
方法1:{
{
$store.state.模块名.属性名 }}
方法2:import {
mapState } from 'vuex';
computed:{
// 注意:对象写法
...mapState({
属性名:state=>state.模块名.属性名
})
}
3.2 命名空间下的getters
方法1:{
{
$store.getters['模块名/属性名'] }}
方法2:import {
mapGetters } from 'vuex'
computed:{
...mapGetters({
属性名:'模块名/属性名'
})
}
3.3 命名空间下的mutations
方法1:$store.commit('模块名/方法名',实参)
方法2:import {
mapMutations } from 'vuex'
methods:{
...mapMutations({
方法名:'模块名/方法名'
})
}
3.4 命名空间下的actions
方法1:$store.dispatch('模块名/方法名',实参)
方法2:import {
mapActions} from 'vuex'
methods:{
...mapActions({
模块名/方法名:'模块名/方法名'
})
}
三、遇到的问题分享
学到这,有没有觉得 这样记忆很麻烦 又有 单页面的状态管理的写法 又有多页面的写法 又分开启命名空间的,这样记忆确实很麻烦 所以我们可以 利用根模块的getters包装子模块的state数据, 可以用 根模块的actions里面访问其他模块的actions或者mutations
// 将子模块的state,变成根模块下的getters
export default new Vuex.Store({
getters:{
namelist:function(state){
// state 表示所有的state数据,包括子模块下的
return state.role.rolelist
},
// 简写
//namelist:state=>state.role.rolelist
}
})
//子模块写法
{
state:()=>({
namelist:[]
}),
namespaced:true
}
// 子模块的actions调用其他模块的actions或者mutations
actions:{
方法名(context){
context.commit('方法名') // 触发自己的mutations方法
context.commit('模块名/方法名') // 触发自己的子模块的mutations方法
context.commit('方法名',null,{
root:true}) // 触发根模块的mutations方法或者没开启命名空间模块下的mutations方法
context.commit('模块名/方法名',null,{
root:true}) // 触发其他模块的mutations方法
context.dispatch('方法名') // 触发自己的actions方法
context.dispatch('模块名/方法名') // 触发自己的子模块的actions方法
context.dispatch('方法名',null,{
root:true}) // 触发根模块的actions方法或者没开启命名空间模块下的actions方法
context.dispatch('模块名/方法名',null,{
root:true}) // 触发其他模块的actions方法
}
},
namespaced:true // 开启了命名空间
总结
好了,今天就学习到这,希望今天的学习能对你有所帮助,记得多多支持哟!
往期文章:
uniapp 图片预览实现
vuex学习篇
扫描二维码关注公众号,回复:
17082518 查看本文章