vuex——在项目中的使用

给公司项目框架引入vuex遇到的坑以及分享的ppt,记录下第一次在小组内分享。

为什么要有状态管理规范?

业务模块功能迭代有这样的特点:

  • 组件单向数据流,在父子组件直接传递
  • 非父子组件会有一些共享的状态,场景比较简单
  • 模块开始分层,跨多层组件状态共享开始变得复杂难懂

上述问题提到的处理方法一般有:

  • 状态提示,把子组件1的状态上升到父组件,再下发到子组件2
  • EventBus,事件总线
  • Redux、Vuex等状态管理仓库

使用状态上升这种方式,能满足比较简单的场景,但如果涉及到频繁切换或者是组件量较多的场景,就比较混乱。

对比下EventBus和Vuex:

eventBus就是一个事件分发机器,使用起来也很方便,this.eventBus.$emit(‘go-quota’, this.userID),就可以把事件和数据都分发出去this.eventBus.$on(‘go-quota’, userID),这样就可以监听事件和获取数据

但是在方便的同时也有隐患,比如出现事件名重复了,还有就是不好管理,只能通过事件名作为唯一的标识,比较难去对数据进行管理,跟踪,不便于维护。

下面看一下项目中出现的eventBus的命名情况:

  • 状态.事件
    image.png
  • 事件.模块.数据
    image.png
  • 数据-事件
    image.png
  • 模块-事件-事件
    image.png
总结:五花八门,没有统一的命名规范

PS:参与调查中,使用过eventBus,75%觉得命名是规范的
剩下25%认为应该以模块功能为主,具体按场景决定

上述这种五花八门的eventBus命名方式,某种程度上来说能避免产生事件命名重复这种问题,可是也带来了另外一个问题,是否应该继续下去?
这种风格不一的命名方式明显是不行的
首先给人的感觉就是混乱,不专业;
其次对于项目维护也不友好,不便于阅读;
所以希望可以在这里统一一下eventBus的命名规范:
模块名-事件名,模块名-事件名-数据名
区别:前者为单独的事件,不抛出数据

①方便跟踪
②语义上容易理解
③按模块区分,命名不容易重复

vuex

Vuex的作用,举个例子:
需要送东西给其他人,没有快递时:
打包准备好要送出去的东西
直接到朋友家,把东西送给朋友
很直接很方便,很费时间

有了快递公司:
打包准备好要送出去的东西
到快递公司,填写物品,收件人等基本信息
快递公司替你送物品到朋友家,工作结束了

当只寄送物品给一个朋友,次数较少,物品又较少的时候,直接去朋友家就挺好的。
但当要频繁寄送给很多朋友很多商品的时候,问题就复杂了。

所以需要状态管理的原因很简单,就是为了把复杂的事情变简单。
需要状态管理规范的原因就是为了更高效地把复杂的事情变简单。

Vuex的使用场景:

  • 同一个模块内遇到多个组件共享状态时
  • 需要跨多组件传递数据时
  • 需要记录数据变化过程时

不适合用的场景:

  • 一些会复用的组件,就不适合使用vuex,vuex应该放业务场景的数据,复用的组件是需要通用的

Vuex规范

调查问卷结果显示:

在开发新模块时,有需要使用的场景,选择使用eventBus的人数刚好与选择用vuex的相等

但是为了避免不同组件之间通信越来越多,代码段里不断的出现$emit和$on,比如以下这样,导致很难查找到每一个事件是从哪里触发。

–建议在开发新的模块的时候,能用vuex或者eventBus的,都使用vuex–
image.png

  • 原因:
    (1)在版本迭代的过程中,同一个模块很可能会越来越多地共享状态
    (2)在使用了vuex之后,后续的使用不会像使用eventBus那样需要监听越来越多的事件,可以减少事件与数据的绑定,可以直接监听到数据的变化。
    (3)对于模块化来说,vuex更加友好。

项目中如何使用Vuex

不同模块可以按需引入当前模块需要的状态仓库(src/store/index.js)
按需加载,能够减少冗余数据的引入,不同模块下的状态仓库互不影响,降低耦合度
在store文件中,有区分不同权限下的store模块(acmpStore:管理员权限
/tenantStore:租户权限/memberStore:子账户权限)

image.png

其中modules下的模块结构如下,包含vuex的状态数据以及基本操作

image.png

  • vuex的核心:
  1. State:共享的状态数据
  2. Mutations:对数据操作的同步方法
  3. Actions:对数据操作的异步方法
  4. Getters:获取数据的方法
  5. Namespaced:以模块名进行区分