TL; DR -- 这个圣诞礼物来得有点晚,但我认为nuxt-socket-io的用户会喜欢它,一旦它被完全理解。现在,可以直接在nuxt.config中为指定的 namespaces 配置 socket.IO 发射器、侦听器和“emitbacks”。本文介绍如何利用新功能。

免责声明:我是 nuxt-socket-io 模块的作者。我在这里介绍一种新的语法,可能需要一些时间才能习惯,但我认为这是一种有意义的语法。以开放的心态接近它。


先决条件:

1.Nuxt Socket.IO 简介- 介绍 Nuxt Socket.IO 和基本设置。

简介:

Socket.IO 是 Web 的实时引擎,而 Nuxt-Socket.IO 模块是让您在 Nuxt 应用程序中使用起来简洁明了的模块。很多时候,希望在组件内部实例化 socket.IO 客户端,然后将通信范围限制在那些组件应该和会关心的范围内。

例如,聊天室组件可能只想与聊天室服务对话,而房间的频道可能只想与该频道的服务对话。在特定频道中发送的消息不应泄漏到房间的其他部分。无论我们将它们称为“通道”还是“房间”,“命名空间”这个词似乎最适合每种情况。另外,虽然“房间”和“频道”将我们的想法限制在“只是一个聊天应用程序”的范围内,但另一方面,“命名空间”这个术语是通用的,允许我们为所有 Web 应用程序考虑范围通信。

除了将组件的 IO 范围限定为给定命名空间的 IO 之外,通常还需要在组件被销毁时发出断开连接(即关闭套接字)的信号。虽然开发人员自己进行清理步骤是一种很好的做法,但对于给定应用程序中的每个组件,这种做法可能很麻烦,也很容易忘记。

因此,考虑到上述内容,nuxt-socket-io 插件和命名空间配置功能具有以下目标:

  • 插件必须允许在nuxt.config中为每个套接字配置命名空间。

  • 该插件必须支持在页面和组件级别配置发射器、侦听器和“发射器”。

  • 对于已配置模块的用户,配置必须与 vuex 选项(侦听器和发射器)的配置一样简单。

  • 新功能必须支持一种新的并且可以说是更直观的箭头 (-->) 语法。这使得 IO 配置更易于版本控制,并在需要时与利益相关者(非开发人员)共享。

  • 配置必须允许支持在指定 IO 事件之前和之后运行挂钩。

  • 默认情况下,插件必须在组件被销毁之前自动断开套接字(通过将teardown: false选项传递给this.$nuxtSocket可以覆盖这一点)。

  • 该插件必须通过鼓励应用程序开发人员编写更少但更一致的代码来让他们的生活更轻松。

  • 插件仍然必须公开 socket.io 客户端实例,以防开发人员需要直接访问客户端 API 方法。

今天,现在可以在nuxt.config中配置命名空间。每个套接字集都可以有自己的命名空间配置,每个命名空间现在可以有发射器、侦听器和发射器。该配置支持每个条目中的箭头语法以帮助描述流程(也支持前/后挂钩指定)。

配置命名空间

本节介绍如何为每个命名空间配置发射器、侦听器和发射器。一般语法是:

preHook] 主体[postHook

有时正文包括“+”、“<--”或“-->”。虽然字符“]”、“[”、“+”、“<--”和“-->”的使用和放置是严格的,但用于钩子、事件和道具的_names_完全是由你决定。

specific 语法如下:

  • 发射器:

preEmit hook] componentMethod + msg --> componentProp [postRx hook

** 怎么想:IO事件由componentMethod触发,事件“componentMethod”通过“msg”发送(在组件中定义为this.msg)。当服务器响应时,响应到组件的 propcomponentProppreEmit钩子在事件发送之前运行,postRx钩子在收到数据后运行。这里的一件好事是_plugin_ 为您创建了componentMethod,因此您不必这样做。只需调用它,它就会起作用。

preEmitpostRx钩子是可选的,但如果使用它们,则需要 "]" 和 "[" 字符,以便插件可以解析它们。这些钩子将在组件的方法部分中定义,例如this.preEmitthis.postRx

msg是可选的,但如果使用,必须使用 '+' 字符

componentMethod由插件自动创建并发送同名事件。如果componentMethod被命名为“getMessage”,它会发送事件“getMessage”

componentProp是可选的,但如果输入,将是在响应返回时随响应设置的属性。这也是可选的,需要在组件上初始定义,否则不会设置。如果您尝试渲染未定义的道具,Vuejs 也会抱怨。如果条目中省略了componentProp,也可以省略箭头“-->”。

  • 听众:

preHook] listenEvent --> componentProp [postRx hook

** 怎么想:当接收到事件“listenEvent”时,propthis.componentProp将被设置为该事件的数据。preHook将在收到数据时运行,但在设置componentProp之前。postRx挂钩将在设置componentProp之后运行。

preHookpostRx挂钩都是可选的。这里接收到数据时调用preHook,但是_before_设置componentProp。设置 prop 后调用postRx钩子。如果计划使用this.preHookthis.postRx,则需要在组件的方法部分中定义。

→ 如果使用箭头语法,当收到listenEvent时,将使用该事件的数据设置componentProp。如果只输入listenEvent,那么插件会尝试在同名组件上设置一个属性。即,如果listenEvent是“progressRxd”,那么插件将尝试在组件上设置this.progressRxd

→ 重要说明:此语法现在也可以在 Vuex 选项中用于突变和操作,这些选项也设置为侦听器。

  • 回传:

preEmitHook] emitEvt <-- watchProp [postAck 挂钩

** 怎么想:当一个组件的属性watchProp改变时,返回事件“emitEvt”。preEmitHook将在数据发出之前运行,postAck将在服务器确认其事件(如果有)之后运行。

preEmitHookpostAck挂钩是可选的。preEmitHook在发出事件之前运行,postAck挂钩在收到确认(如果有)后运行。如果计划使用,则需要在组件的方法中定义this.preEmitHookthis.postAck

watchProp是要使用“myObj.child.grandchild”语法观察的组件的属性。就像你在组件上一样。

emitEvt是在watchProp更改时发送回服务器的事件名称。如果省略watchProp和箭头“<--”,则emitEvt将成为watchProp的两倍。

→ 重要说明:此语法现在也可以在 Vuex 选项中用于发射,但有一个重要区别。在 Vuex(特别是 Nuxt)中,监视属性路径可能需要正斜杠“/”。例如,如果您的商店文件夹中有一个“examples.js”文件,状态属性为“sample”和“sample2”,则必须将 watchProp 指定为“examples/sample”和“examples/sample2”。该规则的例外是“index.js”,它被视为存储根。即,index.js 中的“sample”将被简称为“sample”而不是“index/sample”)


示例配置

以以下配置为例:

nuxt.config.js中:

namespaces: {
  '/index': {
    emitters: ['getMessage2 + testMsg --> message2Rxd'],
    listeners: ['chatMessage2', 'chatMessage3 --> message3Rxd']
  },
  '/examples': {
    emitBacks: ['sample3', 'sample4 <-- myObj.sample4'],
    emitters: [
      'reset] getProgress + refreshInfo --> progress [handleDone'
    ],
    listeners: ['progress']
  }
}

1)首先,我们来分析一下/index的配置。

  • 发射器:

调用getMessage()时,将发送事件“getMessage”和组件的数据this.testMsg。应在组件上定义this.testMsg,但如果不是,则不会发送任何消息(未定义组件数据时插件会发出警告) .收到响应时,组件上的this.messageRxd将设置为该响应。

  • 听众:

当收到chatMessage2时,将设置组件上的this.chatMessage2。当收到chatMessage3时,将设置映射属性this.message3Rxd

2)让我们分析一下/examples的配置。

  • 回传:

当组件中的this.sample3发生变化时,事件sample3将被发送回服务器。当组件中的this.myObj.sample4发生变化时,映射的事件sample4将被发射回来。

  • 个发射器:

当调用this.getProgress()时,firstthis.reset()将被调用(如果已定义),then 事件“getProgress”将与消息this.refreshInfo一起发出。当收到响应时,this.progress将被设置为响应,然后将调用this.handleDone()(如果已定义)

  • 听众:

当接收到事件“进度”时,this.progress将被设置为该数据。

聊天室:一个更令人兴奋的例子

想看一个更令人兴奋的例子吗?查看我的[非常基本] 聊天室示例!

1.克隆我的git repo:https://github.com/richardeschloss/nuxt-socket-io

2.用npm run dev:server运行服务器

  1. 进入聊天室页面:https://localhost:3000/rooms玩得开心! (打开两个浏览器窗口,因为...您至少需要两个客户才能进行对话;如果您愿意,您也可以与自己聊天 :))

我在本系列中的下一篇文章应该有助于解释该示例。

结论

这是关于 nuxt-socket-io 的新命名空间配置功能的相当冗长但重要的讨论。虽然阅读本文所花费的时间可能比预期的要长,但利用您在此处学到的知识,很可能会大大减少您在未来 Web 应用程序上花费的时间。一开始可能是一条崎岖不平的道路,但我认为随着时间的推移,你会习惯这种语法。如果你讨厌它,不用担心......插件仍然会直接公开 socket.io 客户端 API,所以如果需要,你的指尖就会有。

学分/致谢

感谢 Ofoe Apronti@OfoeApronti打开问题并询问。起初,我认为没有一种干净的方法可以创建此功能,因此很早就放弃了。但是,经过更多思考,我认为该解决方案最终可能会满足大多数用户(手指交叉)。

Logo

前往低代码交流专区

更多推荐