Skip to content

Commit 19e335a

Browse files
docs: how to use with Vue 3
1 parent 2e69f70 commit 19e335a

File tree

2 files changed

+259
-0
lines changed

2 files changed

+259
-0
lines changed

src/pages/get-started/index.md

+4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ Let's create a classic CRUD (**C**reate-**R**ead-**U**pdate-**D**elete) applicat
2020

2121
A slightly more complex chat application, introducing [middlewares](/docs/v4/middlewares/) and [rooms](/docs/v4/rooms/) features.
2222

23+
## Front-end frameworks
24+
25+
- [Vue 3](/how-to/use-with-vue)
26+
2327
## How to...
2428

2529
- [deal with cookies](/how-to/deal-with-cookies)

src/pages/how-to/use-with-vue.md

+255
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
---
2+
title: How to use with Vue 3
3+
---
4+
5+
# How to use with Vue 3
6+
7+
This guide shows how to use Socket.IO within a [Vue 3](https://vuejs.org/) application.
8+
9+
## Example
10+
11+
Structure:
12+
13+
```
14+
src
15+
├── App.vue
16+
├── components
17+
│ ├── ConnectionManager.vue
18+
│ ├── ConnectionState.vue
19+
│ └── MyForm.vue
20+
├── main.js
21+
└── socket.js
22+
```
23+
24+
The Socket.IO client is initialized in the `src/socket.js` file:
25+
26+
`src/socket.js`
27+
28+
```js
29+
import { reactive } from "vue";
30+
import { io } from "socket.io-client";
31+
32+
export const state = reactive({
33+
connected: false,
34+
fooEvents: [],
35+
barEvents: []
36+
});
37+
38+
// "undefined" means the URL will be computed from the `window.location` object
39+
const URL = process.env.NODE_ENV === "production" ? undefined : "http://localhost:3000";
40+
41+
export const socket = io(URL);
42+
43+
socket.on("connect", () => {
44+
state.connected = true;
45+
});
46+
47+
socket.on("disconnect", () => {
48+
state.connected = false;
49+
});
50+
51+
socket.on("foo", (...args) => {
52+
state.fooEvents.push(args);
53+
});
54+
55+
socket.on("bar", (...args) => {
56+
state.barEvents.push(args);
57+
});
58+
```
59+
60+
:::info
61+
62+
During development, you will need to enable CORS on your server:
63+
64+
```js
65+
const io = new Server({
66+
cors: {
67+
origin: "http://localhost:8080"
68+
}
69+
});
70+
```
71+
72+
Reference: [Handling CORS](/docs/v4/handling-cors)
73+
74+
:::
75+
76+
:::tip
77+
78+
The event listeners are registered in the `src/socket.js` file, as we strongly advise against registering listeners in your components. More on that [below](#listeners-in-a-component).
79+
80+
:::
81+
82+
You can then use it in your components:
83+
84+
- `src/component/ConnectionState.vue`
85+
86+
```html
87+
<template>
88+
<p>State: {{ connected }}</p>
89+
</template>
90+
91+
<script>
92+
import { state } from "@/socket";
93+
94+
export default {
95+
name: "ConnectionState",
96+
97+
computed: {
98+
connected() {
99+
return state.connected;
100+
}
101+
}
102+
}
103+
</script>
104+
```
105+
106+
- `src/component/ConnectionManager.vue`
107+
108+
```html
109+
<template>
110+
<button @click="connect()">Connect</button>
111+
<button @click="disconnect()">Disconnect</button>
112+
</template>
113+
114+
<script>
115+
import { socket } from "@/socket";
116+
117+
export default {
118+
name: "ConnectionManager",
119+
120+
methods: {
121+
connect() {
122+
socket.connect();
123+
},
124+
disconnect() {
125+
socket.disconnect();
126+
}
127+
}
128+
}
129+
</script>
130+
```
131+
132+
:::tip
133+
134+
The `socket` object can also be initialized without connecting right away with the [`autoConnect`](/docs/v4/client-options/#autoconnect) option:
135+
136+
```js
137+
export const socket = io(URL, {
138+
autoConnect: false
139+
});
140+
```
141+
142+
This can be useful for example when the user must provide some credentials before connecting.
143+
144+
:::
145+
146+
- `src/component/MyForm.vue`
147+
148+
```html
149+
<template>
150+
<form @submit.prevent="onSubmit">
151+
<input v-model="value" />
152+
153+
<button type="submit" :disabled="isLoading">Submit</button>
154+
</form>
155+
</template>
156+
157+
<script>
158+
import { socket } from "@/socket";
159+
160+
export default {
161+
name: "MyForm",
162+
163+
data() {
164+
return {
165+
isLoading: false,
166+
value: ""
167+
}
168+
},
169+
170+
methods: {
171+
onSubmit() {
172+
this.isLoading = true;
173+
174+
socket.timeout(5000).emit("create-something", this.value, () => {
175+
this.isLoading = false;
176+
});
177+
},
178+
}
179+
}
180+
</script>
181+
```
182+
183+
Reference: https://vuejs.org/guide/scaling-up/state-management.html
184+
185+
## Important notes
186+
187+
:::info
188+
189+
These remarks are valid for any front-end framework.
190+
191+
:::
192+
193+
### Hot module reloading
194+
195+
The hot reloading of a file that contains the initialization of a Socket.IO client (i.e. the `src/socket.js` file in the example above) might leave the previous Socket.IO connection alive, which means that:
196+
197+
- you might have multiple connections on your Socket.IO server
198+
- you might receive events from the previous connection
199+
200+
The only known workaround is to do a **full-page reload** when this specific file is updated (or disable hot reloading altogether, but that might be a bit extreme).
201+
202+
Reference: https://vue-loader.vuejs.org/guide/hot-reload.html
203+
204+
### Listeners in a component
205+
206+
We strongly advise against registering event listeners in your components, because it ties the state of the UI with the time of reception of the events: if the component is not mounted, then some messages might be missed.
207+
208+
`src/components/MyComponent.vue`
209+
210+
```html
211+
<script>
212+
import { socket } from "@/socket";
213+
214+
export default {
215+
name: "MyComponent",
216+
217+
data() {
218+
return {
219+
fooEvents: []
220+
}
221+
},
222+
223+
mounted() {
224+
// BAD
225+
socket.on("foo", (...args) => {
226+
this.fooEvents.push(args);
227+
});
228+
}
229+
}
230+
</script>
231+
```
232+
233+
:::note
234+
235+
This is fine in your root component though (since it is always mounted).
236+
237+
:::
238+
239+
### Temporary disconnections
240+
241+
While very powerful, WebSocket connections are not always up and running:
242+
243+
- anything between the user and the Socket.IO server may encounter a temporary failure or be restarted
244+
- the server itself may be killed as part of an autoscaling policy
245+
- the user may lose connection or switch from Wi-Fi to 4G, in case of a mobile browser
246+
247+
Which means you will need to properly handle the temporary disconnections, in order to provide a great experience to your users.
248+
249+
The good news is that Socket.IO includes some features that can help you. Please check:
250+
251+
- [Connection state recovery](/docs/v4/connection-state-recovery)
252+
- [Delivery guarantees](/docs/v4/delivery-guarantees)
253+
254+
255+
[Back to the list of examples](/get-started/)

0 commit comments

Comments
 (0)