:v::zap: Socket.io bindings for Vue.js and Vuex (inspired by Vue-Socket.io)

Overview

Vue-Socket.io-Extended

Build Status Version Downloads License Vue.js 2.x compatible Minified library size Code coverage (codecov) Join us Gitter

Socket.io bindings for Vue.js 2 and Vuex (inspired by Vue-Socket.io)

Edit Vue Socket IO Extended Twitter feed demo

Buy Me a Coffee at ko-fi.com

⚠️ The alpha version of v5 (with Vue 3 support) has been released. Your feedback would be appreciated here

🍒 Features

  • Lightweight and dependency free - only 2kb min gzip
  • Reactive properties $socket.connected and $socket.disconnected
  • Listening and emitting socket.io events inside components
  • Auto-dispatches actions and mutations in multiple namespaced Vuex modules on socket.io events
  • Good TypeScript support (decorator and typing)
  • Can be used with any version of socket.io-client
  • Custom options - tweak the library to better fit your project needs
  • etc...

✔️ Browser Support

Chrome Firefox Safari Opera Edge IE
38+ ✔️ 13+ ✔️ 8+ ✔️ 25+ ✔️ 12+ ✔️ 11+ ✔️

We support only browsers with global usage statistics greater then 1% and last 2 version of each browser (but not dead browsers). Library may work in older browser as well but we don't not guarantee that. You may need addition polyfills to make it work.

🌱 Motivation

I was using Vue-Socket.io for few months. I've liked the idea, but the more I used it the more I faced with bugs, outdated documentation, lack of support, absence of tests and a huge amount of issues 😞 . That slowed down development of the product I was working on. So I ended up with a decision to create my own fork with all the desirable stuff (features/fixes/tests/support/CI checks etc). That's how vue-socket.io-extended was born.

If you'd like to help - create an issue or PR. I will be glad to see any contribution. Let's make the world a better place ❤️

Prerequisites

You must have a running Socket.IO server before starting any Vue/Socket.IO project! Instructions on how to build a Node/Socket.IO server are found here.

Software Requirements

💿 Installation

npm install vue-socket.io-extended socket.io-client

🏁 Initialization

ES2015 (Webpack/Rollup/Browserify/Parcel/etc)

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

const socket = io('http://socketserver.com:1923');

Vue.use(VueSocketIOExt, socket);

Note: you have to pass instance of socket.io-client as second argument to prevent library duplication. Read more here.

UMD (Browser)

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/socket.io-client/dist/socket.io.slim.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-socket.io-extended"></script>
<script>
  var socket = io('http://socketserver.com:1923');
  Vue.use(VueSocketIOExt, socket);
</script>

🚀 Usage

On Vue.js component

Define your listeners under sockets section and they will listen corresponding socket.io events automatically.

new Vue({
  sockets: {
    connect() {
      console.log('socket connected')
    },
    customEmit(val) {
      console.log('this method was fired by the socket server. eg: io.emit("customEmit", data)')
    }
  },
  methods: {
    clickButton(val) {
      // this.$socket.client is `socket.io-client` instance
      this.$socket.client.emit('emit_method', val);
    }
  }
})

Note: Don't use arrow functions for methods or listeners if you are going to emit socket.io events inside. You will end up with using incorrect this. More info about this here

Dynamic socket event listeners (changed in v4)

Create a new listener

this.$socket.$subscribe('event_name', payload => {
  console.log(payload)
});

Remove existing listener

this.$socket.$unsubscribe('event_name');

Reactive properties (new in v4)

$socket.connected and $socket.diconnected are reactive. That means you can use them in expressions

<template>
  <div>
    <span>{{ $socket.connected ? 'Connected' : 'Disconnected' }}</span>
  </div>
</template>

Or conditions

<template>
  <span 
    class="notification" 
    v-if="$socket.disconnected"
  >
    You are disconnected
  </span>
</template>

Or computed properties, methods and hooks. Treat them as computed properties that are available in all components

🌲 Vuex Store Integration

Setup

To set up Vuex integration just pass the store as the third argument. In a Vue CLI project, you might do this in the src/main.js file. Example:

import VueSocketIOExt from 'vue-socket.io-extended';
import { io } from 'socket.io-client';
import store from './store'

const socket = io('http://socketserver.com:1923');

Vue.use(VueSocketIOExt, socket, { store });

Receiving Events

Mutations and actions will be dispatched or committed automatically in the Vuex store when a socket event arrives. A mutation or action must follow the naming convention below to recognize and handle a socket event.

  • A mutation should start with SOCKET_ prefix and continue with an uppercase version of the event
  • An action should start with socket_ prefix and continue with camelcase version of the event
Server Event Mutation Action
chat message SOCKET_CHAT MESSAGE socket_chatMessage
chat_message SOCKET_CHAT_MESSAGE socket_chatMessage
chatMessage SOCKET_CHATMESSAGE socket_chatMessage
CHAT_MESSAGE SOCKET_CHAT_MESSAGE socket_chatMessage

Check the Configuration section if you'd like to use a custom transformation.

Check the Migration from VueSocketIO section if you want to keep actions names in UPPER_CASE.

// In this example we have a socket.io server that sends message ID when it arrives
// so to get entire body of the message we need to make AJAX call the server
import Vue from 'vue'
import Vuex from 'vuex'

// `MessagesAPI.downloadMessageById` is an async function (goes to backend through REST Api and fetches all message data)
import MessagesAPI from './api/message'

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    // we store messages as a dictionary for easier access and interaction
    // @see https://hackernoon.com/shape-your-redux-store-like-your-database-98faa4754fd5
    messages: {},
    messagesOrder: []
  },
  mutations: {
    NEW_MESSAGE(state, message) {
      state.messages[message.id] = message;
      state.messagesOrder.push(message.id);
    }
  },
  actions: {
    socket_userMessage ({ dispatch, commit }, messageId) { // <-- this action is triggered when `user_message` is emmited on the server
      return MessagesAPI.downloadMessageById(messageId).then((message) => {
       commit('NEW_MESSAGE', message);
      })
    }
  }
})

Emitting Events

Events can be sent to the Socket.IO server by calling this._vm.$socket.client.emit from a Vuex mutation or action. Mutation or action names are not subject to the same naming requirements as above. More then one argument can be included. All serializable data structures are supported, including Buffer.

  actions: {
    emitSocketEvent(data) {
      this._vm.$socket.client.emit('eventName', data);
      this._vm.$socket.client.emit('with-binary', 1, '2', { 3: '4', 5: new Buffer(6) });
    }
  }

Namespaced Vuex Modules

Namespaced modules are supported out-of-the-box. Any appropriately-named mutation or action should work regardless of whether it's in a module or in the main Vuex store.

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex);

const messages = {
  state: {
    messages: []
  },
  mutations: {
    SOCKET_CHAT_MESSAGE(state, message) {
      state.messages.push(message);
    }
  },
  actions: {
    socket_chatMessage() {
      console.log('this action will be called');
    }
  },
};

const notifications = {
  state: {
    notifications: []
  },
  mutations: {
    SOCKET_CHAT_MESSAGE(state, message) {
      state.notifications.push({ type: 'message', payload: message });
    }
  },
};

export default new Vuex.Store({
  modules: {
    messages,
    notifications,
  }
})

The above code will:

  • Commit the SOCKET_CHAT_MESSAGE mutation in the messages module
  • Commit the SOCKET_CHAT_MESSAGE mutation in the notification module
  • Dispatch the socket_chatMessage action in the messages module

🎍 ECMAScript / TypeScript decorator (added in v4)

Required: ECMAScript stage 1 decorators. If you use Babel, babel-plugin-transform-decorators-legacy is needed. If you use TypeScript, enable --experimentalDecorators flag.

It does not support the stage 2 decorators yet since mainstream transpilers still transpile to the old decorators.

We provide @Socket() decorator for users of class-style Vue components. By default, @Socket() decorator listens the same event as decorated method name but you can use custom name by passing a string inside decorator e.g. @Socket('custom_event').

Check the example below:

<!-- App.vue -->
<script>
import Vue from 'vue'
import Component from 'vue-class-component'
import { Socket } from 'vue-socket.io-extended'

@Component({})
export default class App extends Vue {
  @Socket() // --> listens to the event by method name, e.g. `connect` 
  connect () {
    console.log('connection established');
  }
  
  @Socket('tweet')  // --> listens to the event with given name, e.g. `tweet`
  onTweet (tweetInfo) {
    // do something with `tweetInfo`
  }
}
</script>

🚵 Usage with Nuxt.js

The key point here is to disable SSR for the plugin as it will crash otherwise. It's a well-know issue and we are going to fix it. Thanks @ll931217 for investigation.

1. Create plugin:

// ~/plugins/socket.io.js
import Vue from 'vue';
import { io } from 'socket.io-client';
import VueSocketIOExt from 'vue-socket.io-extended';

const socket = io('http://localhost:3000');

export default ({ store }) => {
  Vue.use(VueSocketIOExt, socket, { store });
}

2. Then register it:

// nuxt.config.js
module.exports = {
  //...,
  plugins: [
    //...,
    { 
      src: '~/plugins/socket.io.js',
      ssr: false,                    // <-- this line is required
    },
  ]
}

🚵 Usage with Quasar Framework

Register vue-socket.io-extended with a boot file and disable server side rendering

1. Create bootfile:

// ~/boot/socket.io.js
import { io } from 'socket.io-client';
import VueSocketIOExt from 'vue-socket.io-extended';

const socket = io('http://localhost:3000');

export default async ({ store, Vue }) => {
  Vue.use(VueSocketIOExt, socket, { store })
}

2. Then register it:

// quasar.conf.js
module.exports = function (ctx) {
  return {
  //...,
  boot: [
    //...,
    { 
      path: 'socket.io',
      server: false,
    },
  ]
}

⚙️ Configuration

In addition to store instance, vue-socket.io-extended accepts other options. Here they are:

Option Type Default Description
store Object undefined Vuex store instance, enables vuex integration
actionPrefix String 'socket_' Prepend to event name while converting event to action. Empty string disables prefixing
mutationPrefix String 'SOCKET_' Prepend to event name while converting event to mutation. Empty string disables prefixing
eventToMutationTransformer Function string => string uppercase function Determines how event name converted to mutation
eventToActionTransformer Function string => string camelcase function Determines how event name converted to action

FYI: You can always access default plugin options if you need it (e.g. re-use default eventToActionTransformer function):

import VueSocketIOExt from 'vue-socket.io-extended';
VueSocketIOExt.defaults // -> { actionPrefix: '...', mutationPrefix: '...', ... }

ℹ️ Migration from VueSocketIO

For everyone who has migrated from old package VueSocketIO to this new one on existing project. You need to redefine 2 parameters so you will be able to use old store actions names like "SOCKET_EVENT_NAME".

import VueSocketIO from 'vue-socket.io-extended';
import { io } from 'socket.io-client';


const ioInstance = io('https://hostname/path', {
        reconnection: true,
        reconnectionDelay: 500,
        maxReconnectionAttempts: Infinity
});
Vue.use(VueSocketIO, ioInstance, {
        store, // vuex store instance
        actionPrefix: 'SOCKET_', // keep prefix in uppercase
        eventToActionTransformer: (actionName) => actionName // cancel camel case
    }
});

FAQ

Semantic Versioning Policy

This plugin follows semantic versioning.

📰 Changelog

We're using GitHub Releases.

🍻 Contribution

We're more than happy to see potential contributions, so don't hesitate. If you have any suggestions, ideas or problems feel free to add new issue, but first please make sure your question does not repeat previous ones.

🔒 License

See the LICENSE file for license rights and limitations (MIT).

FOSSA Status

Comments
Releases(v5.0.0-alpha.5)
  • v5.0.0-alpha.5(May 14, 2021)

  • v4.2.0(Apr 25, 2021)

  • v5.0.0-alpha.4(Apr 2, 2021)

  • v4.1.0(Mar 24, 2021)

  • v4.0.8(Mar 22, 2021)

  • v4.0.7(Mar 12, 2021)

  • v5.0.0-alpha.3(Jan 18, 2021)

    5.0.0-alpha.3 (2021-01-18)

    Bug Fixes

    • build: exclude vue-class-component from the build (d978515)

    Features

    • dedicated entrypoint for the decorator (df83685)

    BREAKING CHANGES

    • Socket decorator is no longer exported out of the root entry point of vue-socket.io-extended, use the separate entrypoint instead:
    - import { Socket } from 'vue-socket.io-extended'
    + import Socket from 'vue-socket.io-extended/decorator'
    
    Source code(tar.gz)
    Source code(zip)
  • v5.0.0-alpha.2(Jan 17, 2021)

  • v5.0.0-alpha.1(Jan 17, 2021)

  • v4.0.6(Jan 12, 2021)

  • v4.0.5(Sep 29, 2020)

  • v4.0.4(Jul 25, 2020)

  • v4.0.3(May 18, 2020)

  • v4.0.2(May 11, 2020)

    Docs

    • add instructions for quasar framework (#452)
    • fix typo (#439)

    Chores

    • update dependency vue to v2.6.11
    • update dependency vue-class-component to v7.2.3
    • update dependency eslint to v7
    • update dependency rollup to v2.9.1
    • update dependency jest to v26.0.1
    • update dependency babel to v7.9.6
    • update dependency @vue/test-utils to v1.0.2
    Source code(tar.gz)
    Source code(zip)
  • v4.0.1(Oct 20, 2019)

  • v4.0.0(Aug 18, 2019)

    Features

    • Reactive properties this.$socket.connected and this.$socket.disconnected support (Closes #17) Docs
    • ECMAScript / TypeScript @Socket() decorator support (Closes #357) Docs

    Bug fixes

    • Proper unsubscribing from dynamic listeners and non-dynamic listeners #408 #407 #400

    Breaking changes

    • socket.io-client instance moved from this.$socket to this.socket.client. Please check usages before upgrading
    - this.$socket.emit('anything');
    + this.$socket.client.emit('anything');
    
    • Dynamic socket event listeners API change (no more relies on Proxy API)
    - this.$options.sockets.event_name = (payload) => {
    -  console.log(payload)
    - });
    + this.$socket.$subscribe('event_name', (payload) => {
    +  console.log(payload)
    + });
    
    • If you are using library in CommonJS environment you might need to change the usage:
    - const VueSocketIOExt = require('vue-socket.io-extended');
    + const VueSocketIOExt = require('vue-socket.io-extended').default;
    const io = require('socket.io-client');
    
    const socket = io('http://socketserver.com:1923');
    
    Vue.use(VueSocketIOExt, socket);
    

    Other changes

    • IE 11 fully supported now
    • No more security vulnerabilities in the dev dependencies
    • Bundle now properly transpiled to ESM
    • Stop polyfilling dead browsers (e.g. IE 10)
    • Twitter feed example now lives in the repo (more examples soon)
    Source code(tar.gz)
    Source code(zip)
  • v3.2.2(Jul 11, 2019)

    Bug Fixes

    • deps: update dependency camelcase to v5.2.0 (89ea893)
    • deps: update dependency camelcase to v5.3.0 (cefb582)
    • deps: update dependency camelcase to v5.3.1 (f6dc7a4)
    • mixin: fix issue #400, unable to unsubscribe from dynamic listener (d2ccf99) thanks to @jonakirke94

    Chores

    • Rebuild with latest dependencies
    Source code(tar.gz)
    Source code(zip)
  • v3.2.1(Jan 22, 2019)

  • v3.2.0(Dec 2, 2018)

  • v3.1.0(Jul 24, 2018)

    Features

    You can now access default plugin options if you need it (e.g. re-use default eventToActionTransformer function):

    import VueSocketIOExt from 'vue-socket.io-extended';
    VueSocketIOExt.defaults // -> { actionPrefix: '...', mutationPrefix: '...', ... }
    
    • options: make default options read-only (2d9c23e)
    • options: move default options to separate file and export it (2ddbfad)
    • options: move export to plugin field (instead of named export) (7f4960b)
    Source code(tar.gz)
    Source code(zip)
  • v3.0.0(May 26, 2018)

    Options support

    This release introduces options support - hooray :tada: . That means you can tweak the library to better fit your project needs. So now you can:

    • use custom prefix for actions (instead of default socket_), closes #25
    • use custom prefix for mutations (instead of default SOCKET_), closes #25
    • use custom function to convert event to action (instead of default camelcase)
    • use custom function to convert event to mutation (instead of default uppercase)

    Read more in configuration section. That's all for now

    Upgrade guide

    If you are using store - keep reading, if not - stop reading right here because there nothing to update for you :smile:. Previously it was possible to pass store as third argument to enable vuex integration but now third argument is an options object. So, you need to pass store as part of options to enable it.

    In short:

    - Vue.use(VueSocketio, io('http://socketserver.com:1923'), store);
    + Vue.use(VueSocketio, io('http://socketserver.com:1923'), { store });
    
    Source code(tar.gz)
    Source code(zip)
  • v2.0.3(May 16, 2018)

  • v2.0.2(May 2, 2018)

  • v2.0.1(Apr 24, 2018)

  • v2.0.0(Apr 5, 2018)

  • v1.2.1(Apr 2, 2018)

    • chore: integrate with codecov to gather code coverage reports
    • refactor: separate EvenEmitter class from global EvenEmitter instance
    • tests: cover EventEmitter, Observer and mixin by unit tests
    • fix: correctly convert event name to camelcased vuex action name
    Source code(tar.gz)
    Source code(zip)
  • v1.2.0(Mar 31, 2018)

    • feat: move to babel-preset-env instead of babel-preset-es2015 (which is deprecated now)
    • chore: enable CircleCI integration to check PRs before merge
    • chore: setup success build check on CI
    • chore bootstrap eslint to enforce code style based on airbnb configuration
    • chore: bootstrap test environment using jest
    • chore: setup test run on CI
    • refactor: update code based on eslint rules (auto-fix)
    • chore: add script for release generation
    • chore: add script for release note generation
    Source code(tar.gz)
    Source code(zip)
  • v1.1.0(Mar 30, 2018)

  • v1.0.0(Mar 29, 2018)

Owner
Max Lyashuk
JavaScript enthusiast
Max Lyashuk
A template combining TypeORM, Express, Socket.io, and NuxtJS with a custom server setup using ts-node. Includes a lot of features to help bootstrap and supercharge your application.

expressive-nuxt Features 99% TypeScript and uses ts-node <3 Database management with TypeORM API with ExpressJS User authenication and sessions Email

Micheal Pearce 31 Dec 27, 2022
Colubrina - a simple open source chat platform written in Vue, Vuetify, NodeJS, and Socket.io.

Colubrina You can try a public instance of Colubrina at colubrina.troplo.com. This is currently beta software, and may not work as expected. Please fi

null 8 Nov 27, 2022
Real Time Chat Application created with VueJS, Express, Socket IO and MongoDB/Mongoose/Mongo Altas.

?? Astro Chat ?? Real Time Chat Application created with VueJS, Express, Socket IO and MongoDB/Mongoose/Mongo Altas. Contents Demo Tech Stack Features

Lu-Vuong Le 88 Jan 3, 2023
Simple websocket (socket.io) plugin for Vue.js

vue-websocket A socket.io plugin for Vue.js. This package does not support native websockets. At the time, we recommend using vue-native-websocket or

Icebob 532 Dec 17, 2022
Vue socket cluster wrapper

Socket cluster implementation for Vuejs 2 leveraging uws Socket cluster documentation Install npm install vue-socket-cluster --save Usage Configuratio

Nigel Tiany 15 Jul 25, 2021
socket.io와 Vue.js로 구현한 채팅 서비스

개요 : socket.io와 Vue.js로 구현한 채팅 서비스 기간 : 2021.12.22 ~ 2021.12.23 회고 $ cd backend $ npm install $ npm run start $ cd frontend $ npm install $ npm run se

YeonHee 35 Oct 14, 2022
Admin UI for Socket.IO

Admin UI for Socket.IO

Socket.IO 228 Dec 25, 2022
Nodejs + Typescript + Socket.io

CALDAV ?? Required: ?? Nodejs LTS, Python 2.7 or Python 3.x, Docker, MtSQL or the same If you get errors, please read the report file .doc, there will

null 2 May 2, 2022
native websocket with vuex integration

vue-native-websocket · native websocket implementation for Vuejs 2 and Vuex Install yarn add vue-native-websocket # or npm install vue-native-websoc

Nathan 924 Dec 30, 2022
💬 Realtime Chat application made with Vue 3, Fastify and WebSocket.

?? Chatify Full stack Realtime Chat Application made with Vue 3, Fastify and WebSocket. Preview Frontend Stack: Vue 3 & Composition API Bootstrap Vite

Aykut 83 Dec 16, 2022
Vue integration for the Laravel Echo library.

vue-echo Vue 2 integration for the Laravel Echo library. This Vue plugin injects a Laravel Echo instance into all of your vue instances, allowing for

Kerstens Maxim 231 Nov 10, 2022
Redux bindings for VueJS inspired by Vuex.

redux-vuex Redux bindings for VueJS inspired by Vuex. ?? For the old Vue 2 version check out the legacy branch ?? First things first Why don't you use

Alexander Heimbuch 39 Dec 14, 2022
🐙 Web3 blockchain bindings for Vue.js (inspired by Vuefire and Drizzle)

VueWeb3 Vue.js bindings for Web3 1.0 Installation In module environments, e.g CommonJS: npm install vue [email protected] vue-web3 var Vue = require('vue') va

Craig Morris 63 Oct 21, 2022
Lightweight and flexible table component for the web :zap:

Teible Lightweight and flexible table component for the web. No more hassle writing columns outside the template or customizing render template. Packa

Hiển Đào Vinh 56 Dec 9, 2022
:zap: Identify what kinda internet your users are using!

Vue Identify Network Identify the Internet Speed ⚡️ your users have. Demo Link -> Click Here This is on GitHub so let me know if I've b0rked it somewh

Vinayak Kulkarni 60 Apr 22, 2022
🔥 Firebase bindings for Vue.js & Vuex

Vuefire & Vuexfire Synchronize your data and Firebase Cloud Store database in real-time Note: This version currently supports Vue 2 and Firebase 7. Su

vuejs 3.4k Dec 29, 2022
Mobile app development framework and SDK using HTML5 and JavaScript. Create beautiful and performant cross-platform mobile apps. Based on Web Components, and provides bindings for Angular 1, 2, React and Vue.js.

Onsen UI - Cross-Platform Hybrid App and PWA Framework Onsen UI is an open source framework that makes it easy to create native-feeling Progressive We

null 8.7k Jan 4, 2023
Live and reactive PouchDB bindings for Vuejs

Pssst... I'm not working with Vue anymore. This plugin is old and bad. Here is a better alternative: https://github.com/MDSLKTR/pouch-vue vue-pouch Re

Stefan Buhrmester 164 Dec 8, 2022
A Vue plugin for adding Anime bindings to Vue components

Vue-Anime Simple Vue bindings for Anime.js Install $ npm install --save vue-animejs import VueAnime from 'vue-animejs'; Vue.use(VueAnime) Usage Adds

Ben Hammond 174 Nov 14, 2022
Vue bindings for Three.js

vue-threejs [WIP] Three.js bindings for Vue Migrated from react-threejs Demos: react-world, vue-world // import VueThreejs from 'vue-threejs' // below

Fritz Lin 725 Dec 26, 2022