Module介绍
当所有状态都集中到一个比较大的对象时,应用就会变的非常复杂,store
也会变得十分臃肿。
比方说:
一家公司只有老板一个人来管理一样。如果小公司倒还好,公司要是稍微大一点,那就麻烦了。这个时候,老板就会成立各大部门,并给各大部门安排一个主管,把管理的任务分派下去,然后有什么事情需要处理的话,只需要跟这几个主管沟通,由主管再把任务分配下去就行了,这就大大提高了工作效率,也减轻了老板的负担。
那么同样的道理,Module
其实就承担了部门管理员的角色,而 store
就是老板。
为了解决这些问题,Vuex
可以将store
分割成模块。每个模块拥有自己的state
、mutation
、action
、getter
创建Module state进行操作
我需要将用户的state
放到用户里去,订单的放到订单里面去, 于是
这个时候,在组件里面已经可以使用到module
里面的数据了, 例如我的user.js
module
- user.js
可以看到这里面声明了一些store
的基本属性,state
、actions
等
- src/components/VuexDemo/VuexDemo.vue
<template> <div class="VuexDemo"> <div>{{nameOfUserModule}}</div> <div>real name {{realName}}</div> <button @click="changeUserModuleName">修改user module里面的name</button> </div> </template> <script> // import store from '../../store/index'; 因为在main.js 里面引入了store 所以这里就不需要了 直接this.$store就可以了 import { mapState, mapActions, mapGetters } from 'vuex'; export default { created() { this.getUserList(); }, computed: { ...mapState(['userList']), ...mapGetters(['userCount', 'realName']), // realName是user module里面的getter nameOfUserModule: function() { return this.$store.state.user.name // 这里就直接将user的state获取出来了 }, }, methods: { ...mapActions(['getUserList']), changeUserModuleName() { this.$store.dispatch('changeName', '命名空间'); // 这里调用的是user里面的 action } } }; </script>
由以上的例子可以知道: vuex
里面默认mutation
、action
、getter
等都全局的,可以随意调用,但是state
还是私有的
可以看到,这样虽然是将代码拆分了,但是并没有达到真正的拆分,action
等还都是全局的。还没有结束,Vuex还给我们提供了namespace(命名空间)
,这样的话就不用管命名的问题了
Module命名空间
要在module
里面使用命名空间,先要在module
里面设置属性namespaced: true
这样调用action
、getter
等就不能直接调用了,这个时候的action
、getter
已经不是全局,你在调用action
的时候还需要带命名空间
上面是自己去控制前面的命名空间,还有一种简写的办法,可以不用在mapAction等函数带命名空间,例如:
- user.js
参数接受 这是映射是这么写 如果不是mapAction的话直接payload就是值
changeName({commit, rootState}, payload) { commit('setName', payload.payload); },
- 效果
还有个需要注意的地方: 我们知道module里面的state是私有的,那有些场景需要依赖于全局的state,那怎么获取? 从user module的截图里面可以看到,在action、getter参数中有rootState 这个就是根状态 大家可以去玩一下,这里就不做介绍了
模块动态注册
这个基本在项目中很少使用,所以我不做讲解,有兴趣的可以了解一下。我直接把官网的例子搬过来,方便各位看官观看
在 store
创建之后,你可以使用 store.registerModule
方法注册模块:
// 注册模块 `myModule` store.registerModule('myModule', { // ... }) // 注册嵌套模块 `nested/myModule` store.registerModule(['nested', 'myModule'], { // ... })
之后就可以通过 store.state.myModule
和 store.state.nested.myModule
访问模块的状态。
模块动态注册功能使得其他 Vue
插件可以通过在 store
中附加新模块的方式来使用 Vuex
管理状态。例如,vuex-router-sync
插件就是通过动态注册模块将 vue-router
和 vuex
结合在一起,实现应用的路由状态管理。
你也可以使用 store.unregisterModule(moduleName)
来动态卸载模块。注意,你不能使用此方法卸载静态模块(即创建 store
时声明的模块)。
模块重用
就一点,重用会导致模块中的数据 state
被污染,所以和 Vue
中的 data
一样,也使用一个函数来申明 state
即可。(引用数据类型,基础知识,大家可以再回顾一下 这不做讲解)
const MyModule = { state () { return { foo: 'bar' } }, //... }
Thanks
至此,Vuex
核心概念基本完了,如果再出Vuex文章,我会写一些再项目中的坑,避免大家浪费不必要的时间,好的 结束。