【问题标题】:Vuejs and vue-socketio: how to pass socket instance to componentsVuejs 和 vue-socketio:如何将套接字实例传递给组件
【发布时间】:2018-02-15 06:15:25
【问题描述】:

我正在尝试将 Vuejs 与 Vue-Socket.io plugin 一起使用,并且对在组件之间传递套接字的正确方法有疑问。

理想情况下,我只想在整个应用程序中使用一个套接字,因此我想在根实例中实例化套接字,然后将其作为“道具”传递给需要它的组件。这是正确的做法吗?

如果是这样,我做错了什么?我收到的错误是TypeError: this.socket.emit is not a function,所以我可能没有正确传递套接字对象。

使用socket的组件有如下脚本

<script>
  export default {
    name: 'top',
    props: ['socket'],
    data () {
      return {
        Title: 'My Title'
      }
    },
    methods: {
      button_click: function (val) {
        // This should emit something to the socketio server
        console.log('clicking a button')
        this.socket.emit('vuejs_inc', val)
      }
    }
  }
</script>

我在根组件中的初始化如下所示:

import Vue from 'vue'
import VueSocketio from 'vue-socket.io'
import App from './App'
import router from './router'

Vue.use(VueSocketio, 'http://127.0.0.1:5000')
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  template: '<App socket="this.$socket"/>',
  components: {App},
  sockets: {
    connect: function () {
      console.log('Vuejs socket connected.')
    },
    from_server: function (val) {
      console.log('Data from server received: ' + val)
    }
  }
})

然后App通过

<top socket="this.socket"></top>

注意:我知道我也可以将套接字实例化放入需要它的组件中(在本例中为:顶部),或者我可以通过 this.$root.$socket 从根组件访问套接字对象,但我没有也不想做,因为

  • 如上所述,我可能想在其他组件中使用套接字
  • 我不只是想假设根实例中存在套接字对象

本质上,我想从架构的角度来做。

【问题讨论】:

  • 我通过this.$socket将套接字实例从根实例传递到App实例,所以我不能只从App传递this.socket

标签: javascript architecture vuejs2 vue-component


【解决方案1】:

没有必要传递任何东西。 每个组件(和 Vue)上的 Vue-Socket.io 插件 makes the socket availablethis.$socket

我认为你的代码可以工作,只是你似乎没有绑定套接字。

<top socket="this.socket"></top>

应该是

<top :socket="socket"></top>

上面的第一行只是将 socket 设置为字符串“this.socket”。第二个将属性设置为表达式的结果,this.socket

您还需要更改 Vue 的模板:

<App :socket="$socket"/>

【讨论】:

  • 但这在架构上也是正确的使用方式吗?我认为在组件定义中声明性(就预期存在的内容而言)是一件好事,这就是我想显式传递套接字实例的原因。
  • @random_error 这与 Vuex 和 VueRouter 的工作方式相同(分别实现 $store 和 $router 属性),它们是官方插件。您可以提出强有力的论据,认为这是“正确的方式”。另一种方法是使用与 Vuex 的插件集成(如果您正在使用它)并仅调度操作以发送/接收消息。
  • 点了,但是假设我想重用我的组件,或者让其他人重用该组件,它需要一个 socket-io 连接,那么正确的方法是什么然后? vuex $store 和 VueRouter 随 Vue 一起提供,因此它们可能会存在,但 socketio 插件不一定存在。我可能想多了,因为我对 Vue 还很陌生,我只是想实现一个清晰简洁的设计。
  • @random_error 我认为您考虑这些问题没有错。 Vuex 嵌入到每个组件中对我个人来说从来没有多大意义,因为它必然将您的组件与 Vuex 联系起来。这就是为什么存在像 vue-connect 这样的库的原因。然而,Vue 的力量似乎肯定会推动这种方法用于插件,并且社区正在接受它。也就是说,我不认为你采取了错误的方法,我只是认为这可能为时过早。如果/当你需要你可以重构。
  • @random_error 另外,我注意到代码中可能存在错误。你可以试试这个改变。
猜你喜欢
  • 2018-02-02
  • 2020-10-18
  • 2020-12-05
  • 2020-09-29
  • 2019-09-04
  • 2020-07-22
  • 2019-01-21
  • 2019-07-04
相关资源
最近更新 更多