random_error
random_error

Reputation: 375

Vuejs and vue-socketio: how to pass socket instance to components

I am trying to use Vuejs together with the Vue-Socket.io plugin and have a question regarding the correct way of passing the socket between components.

Ideally I want to use only one socket in my whole app, so I want to instantiate the socket in the root instance and then pass it down to the components that need it as a 'prop'. Is that the correct way of doing it?

If so, what am I doing wrong? The error I receive is TypeError: this.socket.emit is not a function so I am probably not passing the socket object correctly.

The component using the socket has the following script

<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>

My initialization in the root component looks like this:

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)
    }
  }
})

And App then passes the socket via

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

NB: I know that I could also either put the socket instantiation into the component that needs it (in this case: top), or I could access the socket object from the root component via this.$root.$socket, but I don't want to do either, because

In essence, I want to do it right from an architectural standpoint.

Upvotes: 5

Views: 4192

Answers (1)

Bert
Bert

Reputation: 82489

There is no need to pass anything. The Vue-Socket.io plugin makes the socket available on every component (and Vue) via this.$socket.

I think your code would work except for the fact that you do not appear to be binding the socket.

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

Should be

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

The first line above will just set socket to the string "this.socket". The second will set the property to the result of the expression, this.socket.

You would also need to change the template for the Vue:

<App :socket="$socket"/>

Upvotes: 4

Related Questions