Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

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

  • As stated above, I might want to use the socket in other components
  • I don't just want to assume a socket object is there in the root instance

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

like image 277
random_error Avatar asked Sep 06 '17 16:09

random_error


1 Answers

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"/>
like image 84
Bert Avatar answered Sep 22 '22 22:09

Bert