Websocketは、クライアントとサーバー間の双方向通信を可能にする強力な方法です。 socket.io は、WebSocketおよび代替トランスポートとの接続処理を簡素化する主要なライブラリの1つです。 コンポーネントでsocket.ioを直接使用できるように、Vueと組み合わせてみましょう。

インストール

まず、YarnまたはNPMを使用してsocket.io-clientvue-socket.ioをインストールしましょう。

# Yarn
$ yarn add socket.io-client vue-socket.io
# NPM
$ npm install socket.io-client vue-socket.io --save

使用法

このガイドでは、 socket.io がローカルで実行されているサーバー(たとえば、ポート4113)が既に存在することを前提としています。

まず、アプリのスタートアップファイルでvue-socket.ioプラグインを有効にします。

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

これで、コンポーネントで直接ソケットイベントにバインドできます。

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

Vuex を使用している場合は、 main.js のプラグイン初期化にVuexストアを追加するだけで、ソケットチャネルがメッセージを受信したときにストアミューテーションを発生させることができます。

main.js
...
import { MyVuexStore } from './my-vuex-store.js'

Vue.use(VueSocketIO, SocketInstance, MyVuexStore)
...

ソケットによってトリガーされるすべてのミューテーションには、SOCKET_というプレフィックスが付きます。

したがって、たとえば、チャネルの名前が messageChannel の場合、対応するVuexミューテーションはSOCKET_MESSAGECHANNELになります。 ストア構成では、次のようになります。

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

悪くないね?

詳細については、vue-socket.ioおよびsocket.ioのドキュメントを参照してください。