Build a live dashboard that updates metrics in real time — simulating a server monitoring or analytics use case.
// composables/useWebSocket.js
import { ref, onUnmounted } from 'vue'
export function useWebSocket(url) {
const status = ref('connecting')
const messages = ref([])
let ws, reconnectTimer
function connect() {
ws = new WebSocket(url)
ws.onopen = () => { status.value = 'connected' }
ws.onmessage = (e) => messages.value.push(JSON.parse(e.data))
ws.onclose = () => {
status.value = 'disconnected'
reconnectTimer = setTimeout(connect, 3000) // auto-reconnect
}
ws.onerror = () => { status.value = 'error' }
}
function disconnect() {
clearTimeout(reconnectTimer)
ws?.close()
}
function send(data) {
if (ws?.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify(data))
}
}
connect()
onUnmounted(disconnect)
return { status, messages, send, disconnect }
}
// stores/metrics.js
export const useMetricsStore = defineStore('metrics', () => {
const cpu = ref([])
const memory = ref([])
const labels = ref([])
const MAX_POINTS = 30
function addDataPoint(data) {
labels.value.push(new Date().toLocaleTimeString())
cpu.value.push(data.cpu)
memory.value.push(data.memory)
if (labels.value.length > MAX_POINTS) {
labels.value.shift()
cpu.value.shift()
memory.value.shift()
}
}
return { cpu, memory, labels, addDataPoint }
})
<script setup>
import { watch } from 'vue'
import { useWebSocket } from '@/composables/useWebSocket'
import { useMetricsStore } from '@/stores/metrics'
const { status, messages } = useWebSocket('ws://localhost:8080/metrics')
const metricsStore = useMetricsStore()
watch(messages, (msgs) => {
const latest = msgs[msgs.length - 1]
if (latest) metricsStore.addDataPoint(latest)
}, { deep: true })
</script>
<template>
<div class="dashboard">
<span :class="`status-${status}`">● {{ status }}</span>
<MetricChart title="CPU %" :data="metricsStore.cpu" color="#FF6384" />
<MetricChart title="Memory %" :data="metricsStore.memory" color="#36A2EB" />
</div>
</template>
All Comments