手写vuex4源码(六)命名空间实现

一、命名空间使用

在子模块对象中添加 namespaced:true,为模块开启命名空间功能;

开启命名空间功能,相当于为每个模块添加独立的作用域,实现模块间状态和事件的隔离;

二、命名空间实现逻辑

在模块注册阶段,会通过类似发布订阅的方式将各模块中的 action、mutation 进行收集并注册,需要根据模块是否开启命名空间状态,为模块拼接命名空间前缀;

所以,可以统一理解为,在事件订阅时,为事件添加对应命名空间标识即可;

三、命名空间实现

1、命名空间标识

在模块收集注册时,添加是否开启命名空间标识

export default class Module {
    constructor(rawModule) {
    	...
        this.namespaced = rawModule.namespaced; // 自己是否有命名空间
    }
}
2、拿到namespace

installModule安装时需要用到namespace,在installModule中调用方法获取命名空间

function installModule(store, rootState, path, module) {
  // 递归安装
  let isRoot = !path.length; // 如果数组是空数组 说明是根,否则不是

  // 下面需要使用namespace,在这里把命名空间进行处理
  const namespaced = store._modules.getNamespaced(path); // [a,c]
  console.log('--',path);
  console.log(namespaced);
  }

_moduleModuleCollection生成的,在ModuleCollection定义getNamespaced方法

getNamespaced(path) {
        let module = this.root // [a,c] a/c
        return path.reduce((namespaceStr, key) => {
            module = module.getChild(key); // 子模块
            return namespaceStr + (module.namespaced ? key + '/' : '')
        }, '')
    }

在这里插入图片描述

3、实现getter、mutation、action的命名空间

以getter为例,拼接时属性名前面加上namespaced

 store._wrappedGetters[namespaced + key] = () => {
      // 通过这个方法去获取最新的state
      return getter(getNestedState(store.state, path));
    };

四、测试

 a模块-------------------
  {{ aCount }}
  <br>
  b模块-------------------
  {{ bCount }}
  <br>
  c模块-------------------
  {{ cCount }}
  <br>
  <button @click="$store.commit('aCount/add',1)">change a</button>
  <button @click="$store.commit('bCount/add',1)">change b</button>
  <button @click="$store.commit('aCount/cCount/add',1)">change c</button>

在这里插入图片描述

五、核心逻辑梳理

  • 在 ModuleCollection 模块收集类中,提供根据 path 获取命名空间标识的能力:getNamespaced(path);
  • 在 installModule 模块安装时,通过调用getNamespaced(path) 获取当前模块的命名空间标识;
  • 在安装/注册mutation、action、getter 时,为对应的事件添加(拼接)上命名空间标识;
    这样,就实现了 Vuex 命名空间 namespaced 功能,即:根模块与各子模块中定义的事件完全独立互不影响;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值