深入理解Vuex 模块化(module)

转载  2017-09-26   作者:ClassName    我要评论

本篇文章主要介绍了Vuex 模块化(module),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

一、为什么需要模块化

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const moduleA = {
 state: {....},
 mutations: {....},
 actions: {....},
 getters: {....}
}
 
const moduleB = {
 state: {....},
 mutations: {....},
 actions: {....},
 getters: {....}
}
 
const store = new Vuex.Store({
 modules: {
 a: moduleA,
 b: moduleB
 }
})
 
store.state.a // moduleA的状态
store.state.b // moduleB的状态

二、模块的局部状态

模块内部的mutation和getter,接收的第一参数(state)是模块的局部状态对象,rootState

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const moduleA = {
 state: { count: 0},
 mutations: {
 increment (state) {
  // state是模块的局部状态,也就是上面的state
  state.count++
 }
 },
 getters: {
 doubleCount (state, getters, rootState) {
  // 参数 state为当前局部状态,rootState为根节点状态
  return state.count * 2
 }
 },
 actions: {
 incremtnIfOddRootSum ( { state, commit, rootState } ) {
  // 参数 state为当前局部状态,rootState为根节点状态
  if ((state.cont + rootState.count) % 2 === 1) {
  commit('increment')
  }
 }
 }
}

三、命名空间(这里一定要看,不然有些时候会被坑)

上面所有的例子中,模块内部的action、mutation、getter是注册在全局命名空间的,如果你在moduleA和moduleB里分别声明了命名相同的action或者mutation或者getter(叫some),当你使用store.commit('some'),A和B模块会同时响应。所以,如果你希望你的模块更加自包含和提高可重用性,你可以添加namespaced: true的方式,使其成为命名空间模块。当模块被注册后,它的所有getter,action,mutation都会自动根据模块注册的路径调用整个命名,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
const store = new Vuex.Store({
 modules: {
 account: {
  namespaced: true,
  state: {...}, // 模块内的状态已经是嵌套的,namespaced不会有影响
  getters: {  // 每一条注释为调用方法
  isAdmin () { ... } // getters['account/isAdmin']
  },
  actions: {
  login () {...} // dispatch('account/login')
  },
  mutations: {
  login () {...} // commit('account/login')
  },
  modules: {  // 继承父模块的命名空间
  myPage : {
   state: {...},
   getters: {
   profile () {...}  // getters['account/profile']
   }
  },
  posts: { // 进一步嵌套命名空间
   namespaced: true,
   getters: {
   popular () {...} // getters['account/posts/popular']
   }
  }
  }
 }
 }
})

启用了命名空间的getter和action会收到局部化的getter,dispatch和commit。你在使用模块内容时不需要再同一模块内添加空间名前缀,更改namespaced属性后不需要修改模块内的代码。

四、在命名空间模块内访问全局内容(Global Assets)

如果你希望使用全局state和getter,roorState和rootGetter会作为第三和第四参数传入getter,也会通过context对象的属性传入action若需要在全局命名空间内分发action或者提交mutation,将{ root: true }作为第三参数传给dispatch或commit即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
modules: {
 foo: {
 namespaced: true,
 getters: {
  // 在这个被命名的模块里,getters被局部化了
  // 你可以使用getter的第四个参数来调用 'rootGetters'
  someGetter (state, getters, rootSate, rootGetters) {
  getters.someOtherGetter // -> 局部的getter, ‘foo/someOtherGetter'
  rootGetters.someOtherGetter // -> 全局getter, 'someOtherGetter'
  }
 },
 actions: {
  // 在这个模块里,dispatch和commit也被局部化了
  // 他们可以接受root属性以访问跟dispatch和commit
  smoeActino ({dispatch, commit, getters, rootGetters }) {
  getters.someGetter // 'foo/someGetter'
  rootGetters.someGetter // 'someGetter'
  dispatch('someOtherAction')  // 'foo/someOtherAction'
  dispatch('someOtherAction', null, {root: true}) // => ‘someOtherAction'
  commit('someMutation') // 'foo/someMutation'
  commit('someMutation', null, { root: true }) // someMutation
  }
 }
 }
}

五、带命名空间的绑定函数

前面说过,带了命名空间后,调用时必须要写上命名空间,但是这样就比较繁琐,尤其涉及到多层嵌套时(当然开发中别嵌套太多,会晕。。)

下面我们看下一般写法

1
2
3
4
5
6
7
8
9
10
11
12
computed: {
 ...mapState({
 a: state => state.some.nested.module.a,
 b: state => state.some.nested.module.b
 }),
 methods: {
 ...mapActions([
  'some/nested/module/foo',
  'some/nested/module/bar'
 ])
 }
}

对于这种情况,你可以将模块的命名空间作为第一个参数传递给上述函数,这样所有的绑定会自动将该模块作为上下文。简化写就是

1
2
3
4
5
6
7
8
9
10
11
12
computed: {
 ...mapStates('some/nested/module', {
 a: state => state.a,
 b: state => state.b
 })
},
methods: {
 ...mapActions('some/nested/module',[
 'foo',
 'bar'
 ])
}

六、模块重用

有时我们可能创建一个模块的多个实例,例如:

  • 创建多个store,他们共用一个模块
  • 在一个store中多次注册同一个模块

如果我们使用一个纯对象来声明模块的状态,那么这个状态对象会通过引用被共享,导致数据互相污染。
实际上Vue组件内data是同样的问题,因此解决办法也是一样的,使用一个函数来声明模块状态(2.3.0+支持)

1
2
3
4
5
6
7
const MyModule = {
 state () {
 return {
  foo: 'far'
 }
 }
}

七、总结

到这里模块化(module)的内容就已经讲完了,本次主要讲解了module出现的原因,使用方法,全局和局部namespaced模块命名空间,局部访问全局内容,map函数带有命名空间的绑定函数和模块的重用。

引用

https://vuex.vuejs.org Vuex官方文档

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

vuex分模块2的更多相关文章

  1. vuex分模块后,如何获取state的值

    问题:vuex分模块后,一个模块如何拿到其他模块的state值,调其他模块的方法? 思路:1.通过命名空间取值--this.$store.state.car.list // OK 2.通过定义该属性的 ...

  2. 对vuex分模块管理

    为什么要分模块: 由于使用单一状态树,应用的所有状态会集中到一个比较大的对象.当应用变得非常复杂时,store 对象就有可能变得相当臃肿.为了解决以上问题,Vuex 允许我们将 store 分割成模块 ...

  3. vuex分模块4

    Vuex下Store的模块化拆分实践 https://segmentfault.com/a/1190000007667542 vue.js vuex 猫切 2016年12月02日发布 赞  |   1 ...

  4. vuex分模块3

    nuxt 踩坑之 -- Vuex状态树的模块方式使用 原创 2017年12月20日 11:24:14 标签: vue / nuxt / vuex / 模块化 / 状态管理 874 初次看到这个模块方式 ...

  5. vuex分模块

    Vuex速学篇:(4)把我们的业务按模块分类 原创 2016年11月29日 10:45:38 8504 文档:http://vuex.vuejs.org/zh-cn/modules.html 这个mo ...

  6. vuex分模块管理

    1.定义命名空间 dog.js export default { namespaced: true, // 局部状态 state: { name: "拉布拉多", age: 1 } ...

  7. 分模块创建maven项目(一)

    maven是一个项目构建和管理的工具. 我们可以通过maven仓库可以实现管理构建(主要是JAR还包括:WAR,ZIP,POM等等). 我们可以通过maven插件可以实现编译源代.产生Javadoc文 ...

  8. Maven02——回顾、整合ssh框架、分模块开发、私服

    1 回顾 1.1 Maven的好处 节省空间 对jar包做了统一管理 依赖管理 一键构建 可跨平台 应用在大型项目可提高开发效率 1.2 Maven安装部署配置 1.3 Maven的仓库 本地仓库 远 ...

  9. 若依项目分模块集成uflo2

    关于若依分模块创建项目可参考:https://www.cnblogs.com/conswin/p/9766186.html 了解uflo2,uflo2是一套由BSTEK自主研发的基于Java的工作流引 ...

随机推荐

  1. 一言不合就写socket的post和get请求(拼内容,然后发出去即可)

    一言不合就写socket的post和get请求.写个桌面程序,利用java写get和post请求.测试成功: SocketReq.java package com.test.CipherIndex; ...

  2. [ACM] POJ 3096 Surprising Strings (map使用)

    Surprising Strings Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5783   Accepted: 379 ...

  3. 初步STL该容器适配器

    容器适配器 特点 容器一定的顺序来实现(让现有的以集装箱堆放/式工作) 分类 1) stack: 头文件 <stack> • 栈 -- 后进先出 2) queue: 头文件 <que ...

  4. String 源码分析

    Java 源码阅读 - String String 类型看起来简单,实际上背后的复杂性基本可以涵盖了整个 Java 设计,涉及到设计模式(不可变对象).缓存(String Pool 的理念).JVM( ...

  5. mysql 优化 读写分离 主从复制

    1:mysql所在服务器内核 优化  ---------此优化可由系统运维人员完成 2:mysql配置参数优化(my.cnf) -------- 此优化需进行压力测试来进行参数调整 3:sql语句及表 ...

  6. VC++互相转码GBK,unicode,utf8

    windows平台下微软的库自带了一些api可用于几种编码格式间的互相转码,其实可以用一个iconv开源跨平台的转码库,那个方法更方便且统一. 使用前要引入头文件和命名空间 #include < ...

  7. Wow6432Node

    64 位版本 Windows 中的注册表分为 32 位注册表项和 64 位注册表项.许多 32 位注册表项与其相应的 64 位注册表项同名,反之亦然. 64 位版本 Windows 包含的默认 64 ...

  8. PySide——Python图形化界面入门教程(二)

    PySide——Python图形化界面入门教程(二) ——交互Widget和布局容器 ——Interactive Widgets and Layout Containers 翻译自:http://py ...

  9. 零元学Expression Blend 4 - Chapter 29 ListBox与Button结合运用的简单功能

    原文:零元学Expression Blend 4 - Chapter 29 ListBox与Button结合运用的简单功能 本章所讲的是运用ListBox.TextBox与Button,做出简单的列表 ...

  10. sql语句查询重复值

    select * from user where name in (select name from user group by name having count(*)>1)