在实时消息传递应用程序中处理状态

Dealing with state in a realtime messaging app

我正在寻找有关在使用 VueJS 2 构建的实时 messaging/chat 应用程序中管理状态的一些指导。

该应用程序由几个组件组成,如下图所示:

到目前为止,我已经实现了显示(假)对话。 App 组件包含一个包含对话对象的数组。对于每个子组件,使用 props 传递相关数据。这真的很简单,而且很有魅力。

现在,我必须处理 actions/mutations 来自嵌套在树中的组件。比如发送一条消息,追加到相应的消息数组中。

我认为这就像在 AppConversationChatWindowInput 组件中分派一个(全局)事件并在 App 组件中处理它一样简单。男孩是我错了。显然,this functionality was removed when Vue 2.0 was introduced 支持 Vuex。我不确定为什么要删除它,因为在某些情况下,这可能是处理事件的一种非常合理的方式。

我想有几个可能的解决方案:

  1. 将 websocket 连接传递给每个子组件。 这在技术上可行。该应用程序将连接到 websocket 服务器,并使用 props 将此连接传递给其子组件。当用户发送消息时,它会被 websocket 服务器回显。 App 组件可以侦听消息并将其附加到消息数组。

    无论技术可行性如何,这对我来说都是一个蹩脚且难以维护的架构。在我看来,除了App之外的任何组件都不应该知道websocket连接,更不用说它的具体实现了。

  2. 在链中的每个组件中手动冒泡事件。 维护起来似乎很痛苦。引入了很多不必要的复杂性和失败点。

  3. 使用全局事件总线。 这是可能的,但为什么输入字段应该依赖于全局事件总线呢?我不喜欢不必要的依赖和耦合。它增加了复杂性并使事情更难测试。

  4. 使用全局数据存储 (Vuex)。 见#3。另一个依赖和增加的复杂性。另外,if 我会选择 Vuex,我将如何在我的组件中检索数据?我是使用组件将它传递下来(就像我现在所做的那样)还是树深处的组件直接从商店中获取它?对我来说,感觉组件知道的比它应该知道的多得多。

有什么想法吗?在我的情况下处理状态的最佳方式是什么?

"I wanted to dispatch a global event" 和 "I don't want to use a global event bus." 之间有点脱节。全局事件总线是您 dispatch/broadcast 全局事件的方式。正如您所指出的,在某些情况下这是一个很好的解决方案。在需要时设置起来并不难,因此没有充分的理由将其放在核心 Vue 中。

您可以将总线创建为 instance property on Vue,以便它可供每个组件使用:

Vue.prototype.$globalEventBus = new Vue();

你会 vm.$dispatch(...) 你会做 vm.$globalEventBus.$emit(...) 并且接收组件可以设置 vm.$globalEventBus.$on(...).

或者,您可以在顶层创建一个总线并将其作为道具传递给子级。这样就避免了全局变量,你也不用担心冒泡了。

最后,正如我在评论中指出的那样,本机事件会冒泡,您可以 catch them at any component higher up the chain. You could catch the event(s) that send messages, or even roll your own 捕捉事件。