说明

定义
文件规范
一般都是单个文件里面写对应的模块,然后export导出,通过顶层的index.js统一引入管理
Vuex 3 和 Vue 2
Vuex 4 和 Vue 3
子模块
index.js 统一引入
使用
使用state
模块内的 getter、mutation、actions
子模块
使用子模块 getter,和state不一样,getters是直接合并到根的getters里面
因此,如果和vuex根下的getters、mutation 重名的话,直接使用会一起执行。
那么我们想让模块的变量、方法独立,要怎么办?看下面命名空间
=====================
命名空间 namespaced
设置



定义
const modules = {foo: {namespaced: true,// 开启命名空间getters: {// 会多3个参数,带root的是vuex根里面的state和getterssomeGetter (state, getters, rootState, rootGetters) {getters.someOtherGetter // -> 'foo/someOtherGetter'rootGetters.someRootOtherGetter // -> 'someRootOtherGetter'},someOtherGetter: state => { ... }},mutations: {// mutations的参数没变化,第一个是state,第二个是外部传入的参数someMutations(state,payload){}},actions: {// 在这个模块中, dispatch 和 commit 也被局部化了// 他们可以接受 `root` 属性以访问根 dispatch 或 commitsomeAction ({ dispatch, commit, getters, rootGetters },payload) {getters.someGetter // -> 'foo/someGetter'rootGetters.someGetter // -> 'someGetter'// 如果要使用root的,使用时可以通过第三个参数{ root: true } 表示dispatch('someOtherAction') // -> 'foo/someOtherAction'dispatch('someOtherAction', null, { root: true }) // -> 'someOtherAction'// 如果要使用root的,使用时可以通过第三个参数{ root: true } 表示commit('someMutation') // -> 'foo/someMutation'commit('someMutation', null, { root: true }) // -> 'someMutation'},someOtherAction (ctx, payload) { ... }}}}
getter 和 mutation
设置命名空间后,现在mutation 和 getter的第一个参数是模块的局部状态对象,并且多了根root的相关内容,方便你想调用根的
action

外部组件中使用
getters
mutation 和 actions

=====================
批量使用模块的mapXXX
之前我们介绍的map方法都是使用根里面的,也就是vuex第一层的
如果是模块,有3种方法
1、通过完整的模块空间名称来查找

2、第一个参数传入模块空间名称,后面写上要使用的属性


3、通过 createNamespacedHelpers 生成一个模块的辅助函数(推荐)
选项API



组合API


useState 和 useGetters 是我们之前封装改造的,但是之前没考虑过模块,因此还要进行改造
hook/useMapper.js
import { computed } from 'vue'import { mapState, useStore } from 'vuex'export function useMapper(mapper, mapFn) {// 拿到store独享const store = useStore()// 获取到对应的对象的functions: {name: function, age: function}const storeStateFns = mapFn(mapper)// 对数据进行转换const storeState = {}Object.keys(storeStateFns).forEach(fnKey => {const fn = storeStateFns[fnKey].bind({$store: store})storeState[fnKey] = computed(fn)})return storeState}

hook/useState.js
import { mapState ,createNamespacedHelpers } from 'vuex'import { useMapper } from './useMapper'// moduleName放第二个参数好点,没有的话相当于用根export function useState(mapper,moduleName) {/*mapState = {a:function(){return this.$store.state.a},b:function(){return this.$store.state.b},}*/let mapperFn = mapStateif(moduleName){mapperFn = createNamespacedHelpers(moduleName).mapState}return useMapper(mapper, mapperFn)}

hook/useGetters.js
import { mapGetters ,createNamespacedHelpers } from 'vuex'import { useMapper } from './useMapper'// moduleName放第二个参数好点,没有的话相当于用根export function useGetters(mapper,moduleName) {/*mapGetters = {a:function(){return this.$store.state.a},b:function(){return this.$store.state.b},}*/let mapperFn = mapGettersif(moduleName){mapperFn = createNamespacedHelpers(moduleName).mapGetters}return useMapper(mapper, mapperFn)}

