probil / vue-socket.io-extended

:v::zap: Socket.io bindings for Vue.js and Vuex (inspired by Vue-Socket.io)
MIT License
629 stars 38 forks source link

Declare for only one component #365

Open Thooto opened 5 years ago

Thooto commented 5 years ago

Hi,

I would need to initiate a socket.io connection only when a component is lazy loaded. (I have an admin section in my UI and I would like the socketio client to not be triggered upon app loading by regular users).

So I would need something equivalent to Vue.use(VueSocketIO) but only for the given component, so that I can still have the sockets: { ... } and this.$socket attributes.

Any idea on how to proceed ? I really can't figure it out ...

Thanks for writing this plugin anyway ! :)

probil commented 5 years ago

Hi, @Thooto

Cool question. This behavior is not supported right now but I think I can add it.

The API may look like so:

<script>
import io from 'socket.io-client'; 

const socket = io('http://socketserver.com:1923', { autoConnect: false })

export default {
  mixins: [
    createSocketIoExtendedMixin(socket)
  ], 
  sockets: {
    connect() {
       console.log('connected');
    }
  }
  mounted: {
     this.$socket.connect()
  }
}
</script>

What do you think about such approach?

Thooto commented 5 years ago

I think that would suit the need perfectly ! (I actually tried something similar using mixins, but couldn't proceed to make it work haha)

However as you wrote in example, autoConnect: false then this.$socket.connect() can also do the trick, I didn't think of it.

Thanks for the super quick answer !

probil commented 5 years ago

However as you wrote in example, autoConnect: false then this.$socket.connect() can also do the trick, I didn't think of it.

@Thooto Yeah. Otherwise it will connect before mounting

munderwoods commented 5 years ago

Any word on this? I would love this behavior. Or a way to connect and disconnect.

Thooto commented 5 years ago

I ended up importing Vue in the component, making it use VueSocketIo, and exporting Vue.extend({ ... }):

<template>
    The component template
</template>

<script>
import Vue from "vue";
import VueSocketIo from "vue-socket.io-extended";
import SocketIo from "socket.io-client";

Vue.use(
    VueSocketIo,
    SocketIo(process.env.VUE_APP_API_URL, {
        autoConnect: false
    })
);

export default Vue.extend({
    data() {
        return {};
    },

    mounted() {
        this.$socket.connect();
    }
});
</script>

Not sure if this is any kind of bad practice, as I didn't check yet if Vue gets loaded twice (making it a heavier app), or if it extends the main Vue module, and then making it possible to potentially use this.$socket in other components, or neither of these options.

Also disconnection can be done by calling this.$socket.disconnect(), for example in the beforeDestroy hook (if that's your question).

I still would be interested in seeing a mixin approach, as I don't know how I could create a mixin to extend this plugin. :)

munderwoods commented 5 years ago

Thanks @Thooto I was starting to go down this route, but second guessed it. How many instances are you working with now, and what's your performance looking like, if you don't mind me asking? I am anticipating having lots of connections so I'm going back and forth on it. Anyway, thanks again.

probil commented 5 years ago

It will work also without special mixin:

// main.js

import VueSocketIOExt from 'vue-socket.io-extended';
import io from 'socket.io-client';

const socket = io('http://socketserver.com:1923', { autoConnect: false });

Vue.use(VueSocketIOExt, socket);

And then in your component:

<script>
export default {
  sockets: {
    connect() {
       console.log('connected');
    }
  },
  mounted() {
     this.$socket.connect();
  },
  beforeDestroy() {
     this.$socket.disconnect();
  }
}
</script>

So in this case, during app loading socket connection will be configured but not actually established. It will be waiting for this.$socket.connect call.

And no, it won't create few instance of Vue or few instances of socket.io - don't worry about that.

The purpose of mixin was to declare $socket only for one componet. But it's not a big deal. And I don't think you'll feel any difference.

@Thooto can you confirm that issue is resolved?

capndave commented 5 years ago

Is this resolved then? @probil I can add this to docs if you want.

probil commented 5 years ago

@capndave I think yes. The approach I've mentioned above is basically the same approach as @Thooto's but with SFC

I can add this to docs if you want.

I'll appreciate if you do.

vibonacci commented 4 years ago

@probil this.$socket.connect() is undefined?

I used the 4 setup lines:

// main.js

import VueSocketIOExt from 'vue-socket.io-extended';
import io from 'socket.io-client';

const socket = io('http://socketserver.com:1923', { autoConnect: false });

Vue.use(VueSocketIOExt, socket);

And in a component simply this.$socket.connect()

UPDATE: Its this.$socket.client.connect(). Plz update :) Thank you for making the library though, it works great and is very intuitive.