I have a Vue 3.x SFC and a custom typescript class Client
as seen below.
The Client
class starts a websocket connection with another server of mine and is going to receive messages containing a user count string and other information.
When I use this.client.userCount = "something"
from mounted()
the page reacts as expected with the span having the new string.
When the Websocket receives the user message with a new string, client.userCount is updated accordingly, but the page does not re-render with the new information.
What do I need adjust for changes made from within the class to be reflected by the reactivity system the same way changes made from outside the class are?
<script setup>
import { Client } from '@/path/to/client';
</script>
<template>
<span>{{ users }}</span> online
</template>
<script>
export default {
data() {
return {
client: new Client(),
}
},
computed: {
users() {
return this.client.userCount;
},
},
}
</script>
Client
that is being imported from Client.ts:
export class Client {
// User counter
public userCount: string = "?";
public connected: boolean = false;
constructor() {
this.websocket = new WebSocket("MYWEBSITE");
this.websocket.onopen = () => {
console.log("client connection open");
this.connected = true;
}
// Process received websocket data
this.websocket.onmessage = (event: any) => {
try {
let data = JSON.parse(event.data);
console.log('message received', data);
switch (data.type) {
case 'users':
this.userCount = data.count.toString();
break;
default:
console.error("unsupported event", data);
}
} catch (err) {
console.log("Error occurred processing message:", err);
console.log(event);
}
};
this.websocket.onclose = () => {
this.connected = false;
console.log('client connection closed');
}
}
}