getter方法的作用 vuex_【第1620期】Vuex中模块(Module)在复杂业务中的应用

前言

今日早读文章由腾讯@红烧牛肉面投稿分享。

正文从这开始~~

模块(Module)是什么

Vuex在简单应用中的使用相信大家都会,但是当应用变得复杂时,store对象就可能变得臃肿,这时可以使用module解决这个问题。

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。

为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割

const moduleA = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }}const moduleB = {
state: { ... },
mutations: { ... },
actions: { ... }}const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB}})
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态
模块(Module)动态注册

在前面的官方示例代码中,moduleA和moduleB都是预先知道的,那如果module无法预知呢?

需求:提供一个具有基础功能的版本,其他团队在此基础版上添加团队的定制功能

在这种需求下,Vuex的module设计采用动态注册(store.registerModule)是比较合适的。

// store.jsexport default new Vuex.Store({})// components/base.vue 基础功能组件import '../modules/base'export default {...};script>// modules/base.js 基础功能moduleimport baseStore from '../store'let store = {
state: {},
mutations: {},
actions: {
init() {
console.log('baseModule:init')}},
getters: {}}
baseStore.registerModule('base', store)// components/team1.vue 团队1定制功能组件import '../modules/team1'export default {...};script>// modules/team1.js 团队1定制功能moduleimport baseStore from '../store'let store = {
state: {},
mutations: {},
actions: {
init() {
console.log('team1Module:init')}},
getters: {}}
baseStore.registerModule('team1', store)// 类似还有 team2和team3...

补充知识点一:卸载模块

你也可以使用 store.unregisterModule(moduleName) 来动态卸载模块。注意,你不能使用此方法卸载静态模块(即创建 store 时声明的模块)。

补充知识点二:保留state

在注册一个新 module 时,你很有可能想保留过去的 state,例如从一个服务端渲染的应用保留 state。你可以通过 preserveState 选项将其归档:store.registerModule(‘a’, module, { preserveState: true })。

当你设置 preserveState: true 时,该模块会被注册,action、mutation 和 getter 会被添加到 store 中,但是 state 不会。这里假设 store 的 state 已经包含了这个 module 的 state 并且你不希望将其覆写。

模块(Module)命名空间

问题:当基础功能和团队定制功能包含相同名称的action、mutation 和 getter时,会同时被触发

// components/base.vuethis.$store.dispatch('init')//输出
baseModule:init
team1Module:init
team2Module:init
team3Module:init

默认情况下,模块内部的 action、mutation 和 getter 是注册在全局命名空间的——这样使得多个模块能够对同一 mutation 或 action 作出响应。

把store打印出来,对上面这句话会有更直观的感受

0fcac4aa3a730fab9e4726f74e7d98d3.png

如果希望你的模块具有更高的封装度和复用性,你可以通过添加 namespaced: true 的方式使其成为带命名空间的模块。当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名。

// components/base.vue// !!!注意:有命名空间时action名称需要加上registerModule时注册的模块名this.$store.dispatch('base/init')// modules/base.js 基础功能moduleimport baseStore from '../store'let store = {
namespaced: true,...}// 有命名空间时dispatch时需要带上这里传入的'base'前缀
baseStore.registerModule('base', store)// modules/team1.js 团队1定制功能moduleimport baseStore from '../store'let store = {
namespaced: true,...}// 同样,有命名空间时,dispatch时需要带上这里传入的'team1'前缀
baseStore.registerModule('team1', store)
// components/base.vuethis.$store.dispatch('base/init')//输出
baseModule:init

再来看下store的打印

43e3e8f9138cb0285426c48f8a0c243b.png
模块(module)访问全局命名空间

需求:基础功能和定制功能需要获取权限信息进行管理

获取权限是个通用的功能,放在全局命名空间是比较合适的

//store.jsexport default new Vuex.Store({
actions:{
getPermission() {
console.log('request permission')}}})

若需要在全局命名空间内分发 action 或提交 mutation,将 { root: true } 作为第三参数传给 dispatch 或 commit 即可。

// modules/base.js 基础功能moduleimport baseStore from '../store'let store = {...
actions: {
init({dispatch}) {
console.log('baseModule:init')
dispatch('getPermission',null,{root:true})}}}// modules/team1.js 团队1定制功能moduleimport baseStore from '../store'let store = {...
actions: {
init({dispatch}) {
console.log('team1Module:init')
dispatch('getPermission',null,{root:true})}}}
store的插件机制

需求:对所有模块的dispatch接口调用进行数据统计

可以通过store的插件机制暴露出每个action的钩子。

//store.jsconst myPlugin = store => {
store.subscribeAction((action, state) => {
console.log( 'report:', action.type)})}export default new Vuex.Store({
plugins: [myPlugin],...})

补充知识点:subscribeAction 是在2.5.0新增的。mutation也是可以通过 subscribe 订阅的。

参考资料
  • Vuex Module

  • Vuex API参考

关于本文
作者:@红烧牛肉面
原文:https://github.com/masterkong/blog/issues/11

f4a9d570acea51eff1ca77353cb787e7.png

他曾分享过

【第1291期】Puppeteer入门简介

为你推荐

【第1586期】基于Redux/Vuex/MobX等库的通用化状态OOP

【第1525期】Vuex、Flux、Redux、Redux-saga、Dva、MobX

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值