Table of Contents
URL: https://www.progressiverobot.com/vuejs-vue-socketio/
Websockets are a powerful way to enable bidirectional communication between the client and the server, and <^>socket.io<^> is one of the leading libraries that simplifies connection handling with websockets and alternative transports. Let's combine it with <^>Vue<^> in order to be able to use <^>socket.io<^> directly in our components!
Installation
First let's install <^>socket.io-client<^> and <^>vue-socket.io<^> using Yarn or NPM.
# Yarn
$ yarn add socket.io-client vue-socket.io
# NPM
$ npm install socket.io-client vue-socket.io --save
Usage
For the purposes of this guide, we're going to assume you already have a server running with <^>socket.io<^> locally on, let's say, port 4113.
First, enable the <^>vue-socket.io<^> plugin in your app startup file:
[label main.js]
import Vue from 'vue';
import socketio from 'socket.io';
import VueSocketIO from 'vue-socket.io';
export const SocketInstance = socketio('http://localhost:4113');
Vue.use(VueSocketIO, SocketInstance)
// The usual app stuff goes here.
...
Now, we can bind to socket events directly in our components:
[label IListenToSockets.vue]
<template>
<div>
<p v-if="isConnected">We're connected to the server!</p>
<p>Message from server: "{{socketMessage}}"</p>
<button @click="pingServer()">Ping Server</button>
</div>
</template>
<script>
export default {
data() {
return {
isConnected: false,
socketMessage: ''
}
},
sockets: {
connect() {
// Fired when the socket connects.
this.isConnected = true;
},
disconnect() {
this.isConnected = false;
},
// Fired when the server sends something on the "messageChannel" channel.
messageChannel(data) {
this.socketMessage = data
}
},
methods: {
pingServer() {
// Send the "pingServer" event to the server.
this.$socket.emit('pingServer', 'PING!')
}
}
}
</script>
Vuex integration
If you're using Vuex, you can have store mutations fired when socket channels receive messages, just by adding your Vuex store to the plugin initialization in <^>main.js<^>.
[label main.js]
...
import { MyVuexStore } from './my-vuex-store.js'
Vue.use(VueSocketIO, SocketInstance, MyVuexStore)
...
All mutations triggered by sockets are prefixed by <^>SOCKET_<^>
So, for example, if your channel is called <^>messageChannel<^>, the corresponding Vuex mutation would be <^>SOCKET_MESSAGECHANNEL<^>. In your store configuration, that would look like this:
[label my-vuex-store.js]
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
state: {
isConnected: false,
socketMessage: ''
},
mutations:{
SOCKET_CONNECT(state) {
state.isConnected = true;
},
SOCKET_DISCONNECT(state) {
state.isConnected = false;
},
SOCKET_MESSAGECHANNEL(state, message) {
state.socketMessage = message
}
}
})
Not bad eh?
For more detailed information, take a look at the vue-socket.io and socket.io documentation.