状态管理指南
在 GitLab 中,我们支持两种客户端状态管理解决方案:Apollo 和 Pinia。 选择其中任何一个作为你的主要状态管理器都不是一件简单的事情。 本页面应该能为你提供如何做出选择的通用指导。
你可能在 GitLab 代码库中看到过 Vuex。Vuex 在 GitLab 中已被弃用,并且不应创建新的 Vuex store。 如果你的应用有 Vuex store,考虑迁移。
状态和数据之间的区别
数据是用户与之交互的信息。 它通常来自外部请求(GraphQL 或 REST)或页面本身。
状态存储关于用户或系统交互的信息。
例如,任何标志都被视为状态:isLoading、isFormVisible 等。
状态管理可用于处理状态和数据。
我是否需要状态管理?
你应该首先倾向于在你的应用中使用标准的 Vue 数据流: 组件定义本地状态,并通过 props 向下传递,通过事件改变它。
然而,在复杂情况下,当状态在多个组件之间共享,而这些组件不是定义该状态的组件的直接后代时,这可能就不够了。 你可以考虑将该状态提升到应用的根级别,但这最终会使根组件臃肿,因为它开始同时做太多事情。
为了处理这种复杂性,你可以使用状态管理解决方案。 下面的部分将帮助你做出这个选择。 如果你仍然不确定,优先使用 Apollo 而不是 Pinia。
Apollo
Apollo,我们与 GraphQL API 的主要接口,也可以用作客户端状态管理器。 了解更多关于 GraphQL 和 Apollo 的信息。
优势
- 非常适合处理来自 GraphQL 请求的数据, 开箱即提供 数据规范化。
- 当 GraphQL 不可用时,可以缓存来自 REST API 的数据。
- 查询会根据 GraphQL schema 进行静态验证。
劣势
- 对于客户端状态管理,比 Pinia 更复杂且更复杂。
- Apollo DevTools:在我们的大部分页面上不能正常工作,Apollo Client 错误很难追踪。
何时选择 Apollo
- 你依赖 GraphQL API
- 你需要特定的 Apollo 功能,例如:
Pinia
Pinia 是 Vue 推荐的客户端状态管理工具。 在 GitLab 上了解更多关于 Pinia 的信息。
优势
- 简单但强大
- 轻量级,约 1.5kb(如 Pinia 网站所述)
- 底层使用 Vue 响应式,API 类似于 Vuex
- 易于调试
劣势
- 开箱即用地无法处理任何高级请求(数据规范化、轮询、缓存等)
- 没有指导的情况下,可能导致与 Vuex 相同的陷阱(过度膨胀的 store)
当你有以下情况时选择 Pinia
- Vue 应用状态的大部分是客户端状态
- 从 Vuex 迁移是高优先级
- 你的应用不主要依赖 GraphQL API,并且你计划在不久的将来不迁移到 GraphQL API
结合使用 Pinia 和 Apollo
我们建议你选择 Apollo 或 Pinia 作为你应用中唯一的状态管理器。 不建议结合使用它们,因为:
- Pinia 和 Apollo 都是全局 store,这意味着共享责任和拥有两个真相来源。
- 心智模型的差异:Apollo 基于配置,而 Pinia 不是。在这些心智模型之间切换是繁琐且容易出错的。
- 同时体验两种方法的缺点。
然而,在某些情况下,结合使用这两种解决方案以寻求特定的好处是可以接受的:
- 如果有大量的客户端状态最适合在 Pinia 中管理。
- 如果特定领域的问题需要在组件内使用 Apollo 进行连贯的 GraphQL 请求。
如果你必须同时使用 Apollo 和 Pinia,请遵循以下规则:
- 切勿在 Pinia store 中使用 Apollo Client。Apollo Client 只应在 Vue 组件或 composable 中使用。
- 不要在 Apollo 和 Pinia 之间同步数据。
- 你的请求应该只有一个真相来源。
向已有 Pinia 的应用添加 Apollo
当你同时满足以下条件时,你可以在组件中拥有 Apollo 数据管理,同时保留现有的 Pinia 状态:
- 需要处理来自 GraphQL 的数据
- 由于迁移成本高,无法从 Pinia 迁移到 Apollo
不要同时尝试用 Apollo 和 Pinia 管理客户端状态(不要与 GraphQL 或 REST 数据混淆), 如果你需要这样做,考虑从 Pinia 迁移到 Apollo。 不要在 Pinia store 中使用 Apollo。
向已有 Apollo 的应用添加 Pinia
首先,强烈建议使用 Apollo 进行客户端状态管理。然而,如果以下所有条件都为真,Apollo 可能不是管理此客户端状态的最佳工具:
- 如果客户端状态的足迹足够大,由于 Apollo 的复杂性,导致实现成本很高。
- 如果客户端状态可以很好地与 Apollo 管理的 GraphQL API 数据解耦。
与 Apollo 一起使用 Vuex
Vuex 在 GitLab 中已被弃用,使用上面的指导选择 Apollo 或 Pinia 作为你的主要状态管理器。 遵循相应的迁移指南:Apollo 或 Pinia。 不要在现有的 Vuex store 之上添加新的 Pinia store,先进行迁移。