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模块化,写法都很多,看我们自己的习惯.
看完之后希望对你有些许帮助

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335