Vuex 如何模块化封装

什么是Vuex

Vuex 是一个专为 Vue.js 应用程序开发的 状态管理模式。它采用 集中式 存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
Vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。

什么场景使用

状态管理 : 就是管理的全局变量。在我们的项目中,特别是较大型的项目,会有很多参数是很多地方都会用到的,比如,一个登录的token,很多页面都需要这个信息,当然我们可以时刻在对应页面操作cookie。所以,状态管理不是必需的,所有状态管理能做的,都能用其他方式实现,但是状态管理提供了统一管理的地方,操作方便,也更加明确。
友情提示 : 只是父组件和子组件用到的,能用$emit和props简单实现的,就不要用它了。

为什么需要模块化

当一个项目比较大时,所有的状态都集中在一起会得到一个比较大的对象,进而显得臃肿,难以维护。为了解决这个问题,Vuex 允许我们将 store 分割成模块(module),每个 module 有自己的 state,getter,mutation,action,甚至还可以往下嵌套模块。

如何分割成模块

(1).目录结构

之前没有模块化的 store 的目录一般如下:

|------ store 文件夹
|----------╘ -- index.js ( 包含所有的 store, getter,mutations ... )

模块化后的 store 的目录一般如下:

|------ store 文件夹
|----------╘ -- modules 模块文件夹
|----------------╘ -- modulesA ( 包含模块所有的 store, getter,mutations ... )
|----------------╘ -- modulesB ( 包含模块所有的 store, getter,mutations ... )
|----------------╘ -- type( 包含所有模块的操作名称 )
|----------╘ -- index 集合所有模块

(2).模块化的具体文件内容
(a).type.js 文件

type.js 文件用于团队协作开发, 防止操作名称重复, 起到一个约束作用, 如下:

export default {
    // modulesA
    UP_HANDLER1: 'UP_HANDLER1', // 操作1
    GET_HANDLER2: 'GET_HANDLER2', // 操作2
    DEL_HANDLER3: 'DEL_HANDLER3', // 操作3
    // modulesB
    UP_HANDLER1: 'UP_HANDLER1', // 操作1
    GET_HANDLER2: 'GET_HANDLER2', // 操作2
    DEL_HANDLER3: 'DEL_HANDLER3', // 操作3
}
(b).modulesA.js 文件:

modulesA 包含自己的 state,getter,mutation,action , 其他模块也一样, 如下:

import types  from './types' // 按需引入常量
const state = {
    state1 : "",  
    state2 : {}, 
    state3 : []
}
const getters = {
}
const mutations = {
    [types.UP_HANDLER1](state, HANDLER_INFO) {           
        state.state1 = HANDLER_INFO;            
    },
    [types.GET_HANDLER2](state, HANDLER_INFO) {           
        state.state2 = HANDLER_INFO;            
    }
}
const actions = {
}
export default{
    namespaced: true,
    state,
    getters,
    mutations
}

命名空间:namespaced: true:当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名,也就是说,我们在调用这些方法时,需要加上这个文件的路径(比如我要访问这个文件中的state里边的某个属性:this.$store.state.modulesA。后边这个modulesA就是多了个modulesA.js模块名,因为如果不加模块名,那我们会访问所有模块中的属性,那就乱了),所以我们要加上命名空间,相当于独立的区块去使用,模块和模块之间互不干扰。

(c).index.js 文件

集成了所有的模块内容, 内容如下:

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
import modulesA from './modules/modulesA.js'
import modulesB from  './modules/modulesB.js'
// 导出所有状态
export default new Vuex.Store({
    // state,
    // getters,
    // mutations,
    // actions,
    modules: {
        modulesA , modulesB 
    }
})

以上是模块化的其中一种分割方式, 可根据项目需要自行分割, 还可以将每个模块的 state, getter, mutation 等深层次的分割出去, 有兴趣的童鞋们可以试试

如何使用模块化后的状态

普通状态的读取 / 提交:

export default {
    data:{
        return {
            stateInfo: ''
        }
    },
    computed: {
        // 实时拿到更新后的状态
        state1(){
            return this.$store.state.state1;
        }  
    },
    methods:{
       //  获得状态值
       getInfo(){
          this.stateInfo = this.$store.state.state1
          return this.stateInfo;
       },
       // 提交更新状态值
       upInfo(){
            this.$store.commit('更新操作的名称', 更新的数据);
       }
    }
}

模块化封装后的状态的读取 / 提交, 与之前略有不同,我们可以和平常一样,直接用this.$store.state.modulesA.state1来获取到 state 中的 state1 内容。我们今天说说在项目中最常使用的:辅助函数mapStatemapGettersmapActionsmapMutations
简单说两个mapStatemapActions,深入理解可去看官网

(1).引入辅助函数
import { mapState, mapMutations } from 'vuex' 

这俩函数, 前者写在计算属性computed中,后写是方法写在 methods中
在写入时,需要用到展开符...,它可以将内容一 一的展开

mapState : 获取state中的state1:

export default {
    computed: {
        // 方法一
        // ...mapState({
        //   a: state => state.modulesA.state1
        // }),
        方法二
       ...mapState('modulesA',{
          b: state => state.state1
        })
    }
}

mapMutations : 提交状态

export default {
   methods: {
       // 更新状态值 
       // 用了mapMutations,它会将这个路径直接映射成 commit 方法
       upDateInfo(){
           this.upInfo1('更新的数据'); // 方法一
           this.UP_HANDLER1('更新的数据'); // 方法二
           this.upInfo3('更新的数据'); // 方法三
       },
       // 方法一
       //upInfo1 (dataInfo) {
       //  this.$store.commit('modulesA/UP_HANDLER1', dataInfo)
       //}
       // 方法二
       // ...mapMutations('modulesA', ['UP_HANDLER1'])
        // 方法三
       ...mapMutations('modulesA', {
           upInfo3 : 'UP_HANDLER1' (与 type.js 文件的命名保持一致)
       })
   }
}

这就是vuex模块化,写法都很多,看我们自己的习惯.
看完之后希望对你有些许帮助

你可能感兴趣的:(Vuex 如何模块化封装)