我正在寻找有关在使用 VueJS 2 构建的实时消息/聊天应用程序中管理状态的一些指导。
该应用程序由几个组件组成,如下图所示:
到目前为止,我已经实现了显示(虚假)对话。 App 组件包含一个包含对话对象的数组。对于每个子组件,使用 props 传递相关数据。这真的很简单,而且很有魅力。
现在,我必须处理来自深深嵌套在树中的组件的 Action /变化。例如,发送消息并将其附加到相应的消息数组中。
我认为这就像在 AppConversationChatWindowInput 组件中分派(dispatch)一个(全局)事件并在 App 组件中处理它一样简单。男孩是我错了。显然,this functionality was removed when Vue 2.0 was introduced支持 Vuex。我不确定为什么将其删除,因为在某些情况下,这可能是处理事件的一种完全合理的方式。
我想有几个可能的解决方案:
将 websocket 连接传递给每个子组件。这在技术上可行。该应用程序将连接到 websocket 服务器,并使用 props 将此连接传递给其子组件。当用户发送消息时,它会被 websocket 服务器回显。 App 组件可以监听消息并将其附加到消息数组。
无论技术可行性如何,我都觉得这是一个蹩脚且难以维护的架构。在我看来,除了 App 之外,没有任何组件应该知道 websocket 连接,更不用说它的具体实现了。
在链中的每个组件中手动冒泡事件。 维护起来似乎很痛苦。引入了很多不必要的复杂性和故障点。
使用全局事件总线。 这是可能的,但为什么输入字段应该依赖于全局事件总线呢?我不喜欢不必要的依赖和耦合。它增加了复杂性并使事情更难测试。
使用全局数据存储 (Vuex)。 见#3。另一个依赖和增加的复杂性。此外,如果我愿意使用 Vuex,我将如何检索组件中的数据?我是使用组件将它传递下来(就像我现在所做的那样)还是树深处的组件直接从商店中获取它?对我来说,感觉组件知道的比它应该知道的多得多。
有什么想法吗?在我的情况下处理状态的最佳方式是什么?
最佳答案
“我想分派(dispatch)一个全局事件”和“我不想使用全局事件总线”之间有点脱节。全局事件总线是您调度/广播全局事件的方式。正如您所指出的,在某些情况下这是一个很好的解决方案。在需要时设置起来并不难,因此没有充分的理由将其放在核心 Vue 中。
您可以将总线创建为 instance property on Vue所以它对每个组件都是可用的:
Vue.prototype.$globalEventBus = new Vue();
如果你有 vm.$dispatch(...)
你会做 vm.$globalEventBus.$emit(...)
和接收组件可以设置vm.$globalEventBus.$on(...)
。
或者,您可以在顶层创建一个总线并将其作为 Prop 传递给子级。这避免了全局变量,您不必担心冒泡。
最后,正如我在评论中指出的那样,本地事件冒泡,您可以 catch them at any component higher up the chain .您可以捕获发送消息的事件,甚至 roll your own要捕捉的事件。
关于javascript - 在实时消息传递应用程序中处理状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46668006/