我们平时开发的大部分项目,由于复杂度不够,很少使用 Vuex、Redux 等状态管理库,就算引入了 Vuex 这些库,也只是当作一个全局数据引用,并非对应用状态进行管理。
但一旦页面的复杂度比较高,必然要引入状态管理,今天就聊聊我理解中的状态管理。
如果涉及到举例,由于我对 Vuex
更熟悉,团队内也大多比较熟悉 Vue
,因此会使用Vuex
作例子。
到底什么时候应该使用状态管理
举例几个需要用 Vuex 的例子:
例子一
// Page.vue
<page>
<component-a />
<component-b />
</page>
// ComponentA.vue
<div>
<component-a-child />
</div>
比如这个例子中,<component-a-child />
想和 <component-b />
通信,使用事件传递来解决非常麻烦。
当然也可以使用 EventBus,加一个全局的 vue 实例解决,但用 EventBus 还需要去关心事件的绑定解绑,需要手动处理事件,当这类组件,就会变得非常麻烦。
最好的解决办法就是抽象出通用的组件状态,放到 state 里面,接着通过 action/mutation 改变通用状态,而需要这些状态的组件则自己调用(mapState/mapGetter),不需要去关注组件之间的关系。
例子二
// Page.vue
<page>
<topic-list
:list="list"
:activity="activity"
:user="user" />
</page>
// TopicList.vue
<div>
<topic-header :list="list" :activity="activity" :user="user" />
<template v-for="item in list">
<topic :list="list" :data="item" :activity="activity" :user="user" />
</template>
</divt
这个例子里 :list="list" :activity="activity" :user="user"
在被不断的传递,实际里面的组件可能只需要里面的一两个属性。
当然,例子里面的代码比较简单,也可以通过合理的组件设计来解决。
但一旦碰到这种某几个状态数据不断被其子组件以及后代组件使用的状况,可以考虑使用状态管理来解耦,可能使代码更加简洁。
状态管理解决了什么
- 最主要是解耦,把组件与组件之间的复杂关系解耦为数据与数据的关系,组件仅作单纯的数据渲染,而且由于是单一数据源,整体上非常便于维护。
以前是:
现在是:
- 由于单一数据源 + 数据不可变,带来了应用状态的快照,可以很方便的实现前进 / 后退以及历史记录管理。
- 可测试性,可以分别针对视图和数据进行测试,而不是混淆在一起,导致测试难度极大。
状态管理带来的新问题
最主要是由于解决使得单个组件复杂度的提升,但相比整体复杂度的降低以及更高的可维护性,这点代价是完全值得。