大家好!今天我将分享一个简单却强大的实时库存仪表盘项目,基于Vue.js和WebSocket技术。这个项目适合初学者学习前端实时数据处理,也能为你的技术博客或作品集增添亮点!通过这个教程,你将学会如何使用WebSocket实现实时数据更新,创建用户友好的界面,并处理断线重连等实际场景。快来跟我一起动手打造吧!

项目简介

这个实时库存仪表盘展示了库存预警和总库存量,通过WebSocket从服务器获取实时数据。界面简洁直观,包含动态时间显示、库存数据列表和错误提示弹窗。整个项目使用Vue.js 2.6.14和纯HTML/CSS,无需复杂依赖,打开浏览器即可运行,适合快速上手和分享。

功能亮点

  • 实时数据更新:通过WebSocket接收服务器推送的库存数据,动态更新界面。

  • 心跳机制:每10秒发送心跳消息,确保连接稳定。

  • 断线重连:连接断开后自动每3秒尝试重连,并显示友好提示。

  • 简洁界面:包含实时时间、库存预警列表和总库存展示,易于扩展。

  • 零依赖部署:通过CDN加载Vue.js,无需本地开发环境。

项目代码解析

以下是项目的核心代码(完整代码见文末)。我将重点讲解WebSocket的关键逻辑和实现细节。

1. HTML结构

仪表盘的HTML结构分为三部分:

  • 头部:显示标题和实时时间。

  • 内容区:展示库存预警列表和总库存量。

  • 弹窗:在WebSocket连接失败时显示提示。

<div id="app" class="container"><div class="header"><h1>实时库存仪表盘</h1><span class="time">{{ currentTime }}</span></div><div class="content"><div class="data-box"><h2>库存预警</h2><div class="data-item" v-for="product in products" :key="product.id">{{ product.name }}: {{ product.quantity }} (万)</div></div><div class="data-box"><h2>库存总量</h2><div class="data-item">总库存: {{ totalStock }} 万</div></div></div><div class="popup" :class="{ show: isPopupVisible }"><p>数据连接失败,正在尝试重新连接...<br>请确保网络正常或联系技术人员。</p></div>
</div>

2. WebSocket核心逻辑

WebSocket是实现实时数据更新的关键。以下是Vue.js中与WebSocket相关的核心方法:

  • 连接WebSocket:初始化WebSocket连接,发送初始消息,并启动心跳机制。

connectWebSocket() {this.ws = new WebSocket('ws://1.94.0.197:6061/websocket');this.ws.onopen = () => {console.log('WebSocket已连接');if (this.isReconnecting) {this.isPopupVisible = false;this.isReconnecting = false;}this.ws.send(JSON.stringify({ type: 'init' }));this.startHeartbeat();};// ... 其他事件处理
}

心跳机制:每10秒发送心跳消息,保持连接活跃。

startHeartbeat() {this.heartbeatInterval = setInterval(() => {if (this.ws && this.ws.readyState === WebSocket.OPEN) {this.ws.send(JSON.stringify({ type: 'heartbeat' }));}}, 10000);
}

断线重连:连接断开后,每3秒尝试重连,并显示弹窗提示。

reconnect() {this.isReconnecting = true;setTimeout(() => {console.log('尝试重连WebSocket...');this.connectWebSocket();}, 3000);
}

数据更新:接收服务器数据并更新界面。

updateData(data) {this.products = data.getLowStock || [];this.totalStock = data.getCount?.totalStock || 0;
}

3. CSS样式

样式设计简洁现代,使用了浅色背景和卡片式布局,确保界面清晰且美观:

  • 容器:居中显示,带阴影和圆角。

  • 弹窗:居中弹出,红色文字提示错误。

  • 响应式:适配不同屏幕尺寸。

.container {max-width: 800px;margin: 0 auto;background: white;padding: 20px;border-radius: 8px;box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
.popup {position: fixed;top: 50%;left: 50%;transform: translate(-50%, -50%);background: white;padding: 20px;border-radius: 8px;box-shadow: 0 4px 16px rgba(0,0,0,0.2);display: none;
}
.popup.show { display: block; }

4. Vue.js逻辑

  • 数据绑定:使用Vue的响应式数据(如products和totalStock)动态更新界面。

  • 生命周期管理

    • mounted:启动时间更新和WebSocket连接。

    • beforeDestroy:清理定时器和WebSocket连接,避免内存泄漏。

  • 时间显示:每秒更新当前时间,格式为“YYYY-MM-DD HH:mm:ss”。

updateTime() {const now = new Date();this.currentTime = now.toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit',hour: '2-digit', minute: '2-digit', second: '2-digit'});
}

完整代码

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>WebSocket 实时库存仪表盘</title><script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.min.js"></script><style>body { font-family: Arial, sans-serif; background-color: #f0f2f5; margin: 0; padding: 20px; }.container { max-width: 800px; margin: 0 auto; background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); }.header { display: flex; justify-content: space-between; align-items: center; background: #2c3e50; color: white; padding: 10px 20px; border-radius: 8px 8px 0 0; }.header h1 { margin: 0; font-size: 24px; }.time { font-size: 16px; }.content { padding: 20px; }.data-box { margin-bottom: 20px; }.data-box h2 { margin: 0 0 10px; font-size: 18px; color: #34495e; }.data-item { padding: 10px; background: #ecf0f1; border-radius: 4px; margin: 5px 0; }.popup { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; padding: 20px; border-radius: 8px; box-shadow: 0 4px 16px rgba(0,0,0,0.2); display: none; }.popup.show { display: block; }.popup p { margin: 0; font-size: 16px; color: #e74c3c; text-align: center; }</style>
</head>
<body><div id="app" class="container"><div class="header"><h1>实时库存仪表盘</h1><span class="time">{{ currentTime }}</span></div><div class="content"><div class="data-box"><h2>库存预警</h2><div class="data-item" v-for="product in products" :key="product.id">{{ product.name }}: {{ product.quantity }} (万)</div></div><div class="data-box"><h2>库存总量</h2><div class="data-item">总库存: {{ totalStock }} 万</div></div></div><div class="popup" :class="{ show: isPopupVisible }"><p>数据连接失败,正在尝试重新连接...<br>请确保网络正常或联系技术人员。</p></div></div><script>new Vue({el: '#app',data() {return {products: [],totalStock: 0,currentTime: '',isPopupVisible: false,ws: null,isReconnecting: false,heartbeatInterval: null,timer: null};},mounted() {this.updateTime();this.timer = setInterval(this.updateTime, 1000);this.connectWebSocket();},beforeDestroy() {clearInterval(this.timer);clearInterval(this.heartbeatInterval);if (this.ws) this.ws.close();},methods: {updateTime() {const now = new Date();this.currentTime = now.toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit',hour: '2-digit', minute: '2-digit', second: '2-digit'});},connectWebSocket() {this.ws = new WebSocket('ws://1.94.0.197:6061/websocket');this.ws.onopen = () => {console.log('WebSocket已连接');if (this.isReconnecting) {this.isPopupVisible = false;this.isReconnecting = false;}this.ws.send(JSON.stringify({ type: 'init' }));this.startHeartbeat();};this.ws.onmessage = (event) => {const data = JSON.parse(event.data);this.updateData(data);};this.ws.onerror = (error) => {console.error('WebSocket错误:', error);};this.ws.onclose = () => {console.log('WebSocket连接关闭');this.isPopupVisible = true;this.stopHeartbeat();if (!this.isReconnecting) {this.reconnect();}};},reconnect() {this.isReconnecting = true;setTimeout(() => {console.log('尝试重连WebSocket...');this.connectWebSocket();}, 3000);},startHeartbeat() {this.heartbeatInterval = setInterval(() => {if (this.ws && this.ws.readyState === WebSocket.OPEN) {this.ws.send(JSON.stringify({ type: 'heartbeat' }));}}, 10000);},stopHeartbeat() {clearInterval(this.heartbeatInterval);},updateData(data) {this.products = data.getLowStock || [];this.totalStock = data.getCount?.totalStock || 0;}}});</script>
</body>
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/921638.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/921638.shtml
英文地址,请注明出处:http://en.pswp.cn/news/921638.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

leecode100——接雨水

题目 双指针 思路1 使用参数存储从左往右&#xff08;从右往左同理&#xff09;遍历时的最高的柱子&#xff0c; 然后移动左右的指针&#xff0c;每次移动左右指针中偏向小的&#xff0c; 如果当前指针指的柱子小于最高的柱子&#xff0c;就会存在接到水。 思路2 把水看作柱子&…

复古胶片风格街拍人像Lr调色教程,手机滤镜PS+Lightroom预设下载!

调色教程复古胶片风格街拍人像 Lightroom 调色&#xff0c;通过模拟经典胶片相机的色彩科学&#xff0c;为现代数码照片注入怀旧韵味。这种调色手法注重低饱和度色彩、柔和的高光过渡和丰富的暗部细节&#xff0c;配合适度的颗粒感&#xff0c;营造出时光沉淀的质感。特别适合街…

Linux的gpio子系统

GPIO其实也是某个pin的功能之一。上一小节讲解了 pinctrl 子系统&#xff0c;pinctrl 子系统重点是设置 PIN(有的 SOC 叫做 PAD)的复用和电气属性&#xff0c;如果 pinctrl 子系统将一个 PIN 复用为 GPIO 的话&#xff0c;那么接下来就要用到 gpio 子系统了。gpio 子系统顾名思…

VC++ CPU指令集检测工具实现原理

&#x1f4c8; VC CPU指令集检测工具实现原理 例图&#xff1a;&#x1f9e0; 1. 核心原理&#xff1a;CPUID指令 // 使用CPUID指令获取CPU信息 int cpuInfo[4] { -1 }; __cpuid(cpuInfo, 0); // 调用CPUID指令 int nIds cpuInfo[0]; // 获取最大标准功能号CPUID指令工作流程…

大模型微调理论、实战:LLaMA-Factory、Unsloth

概述 微调&#xff0c;Fine-Tuning&#xff0c;简称FT&#xff0c;可理解为对LLM的定制&#xff0c;目的是增强专业领域知识&#xff0c;并优化特定任务的性能。通过在特定数据集上微调一个预训练模型&#xff0c;可实现&#xff1a; 更新知识&#xff1a;引入新的领域专属信…

【LCA 树上倍增】P9245 [蓝桥杯 2023 省 B] 景区导游|普及+

本文涉及知识点 树上倍增 P9245 [蓝桥杯 2023 省 B] 景区导游 题目描述 某景区一共有 NNN 个景点&#xff0c;编号 111 到 NNN。景点之间共有 N−1N-1N−1 条双向的摆渡车线路相连&#xff0c;形成一棵树状结构。在景点之间往返只能通过这些摆渡车进行&#xff0c;需要花费…

基于Python+Streamlit的旅游数据分析与预测系统:从数据可视化到机器学习预测的完整实现

&#x1f3de;️ 基于PythonStreamlit的旅游数据分析与预测系统&#xff1a;从数据可视化到机器学习预测的完整实现 &#x1f4dd; 前言 在大数据时代&#xff0c;旅游行业的数据分析变得越来越重要。如何从海量的旅游数据中挖掘有价值的信息&#xff0c;并进行准确的销量预测&…

飞算JavaAI全链路实战:智能构建高可用电商系统核心架构

飞算JavaAI全链路实战&#xff1a;智能构建高可用电商系统核心架构 前言&#xff1a;AI编程新时代的电商系统开发范式变革 在当今数字经济时代&#xff0c;电商系统作为企业数字化转型的核心载体&#xff0c;其复杂度和技术要求与日俱增。一个完整的电商系统不仅需要处理商品、…

论文精读(五):面向链接预测的知识图谱表示学习方法综述

笔者链接&#xff1a;扑克中的黑桃A 专栏链接&#xff1a;论文精读 本文关键词&#xff1a;知识图谱; 表示学习; 链接预测; 多元关系; 超关系 引 诸位技术同仁&#xff1a; 本系列将系统精读的方式&#xff0c;深入剖析计算机科学顶级期刊/会议论文&#xff0c;聚焦前沿突破…

Roo Code之自定义指令(Custom Instructions),规则(Rules)

在Roo Code 中&#xff0c;Custom Instructions 可以通过Instructions 设定和Rules 规则文件实现。什么是Custom Instructions&#xff1f; 自定义指令(Custom Instructions)定义了超出Roo基本角色定义范围的具体行为、偏好和约束。示例包括编码风格、文档标准、测试要求和工作…

9/8我是ai大师

一、变量定义部分&#xff08;理解程序的 "记忆"&#xff09;c运行/* USER CODE BEGIN PV */ static uint8_t last_button_state 1; // 初始为高电平&#xff08;未按下&#xff09; static uint8_t device_mode 0; // 设备模式&#xff1a;0LD1, 1LD3, 2蜂鸣器, 3…

前沿重器[74] | 淘宝RecGPT:大模型推荐框架,打破信息茧房

前沿重器栏目主要给大家分享各种大厂、顶会的论文和分享&#xff0c;从中抽取关键精华的部分和大家分享&#xff0c;和大家一起把握前沿技术。具体介绍&#xff1a;仓颉专项&#xff1a;飞机大炮我都会&#xff0c;利器心法我还有。&#xff08;算起来&#xff0c;专项启动已经…

jenkins加docker 部署项目

jenkins加docker 部署springboot项目 1项目结构Dockerfile 内容 FROM openjdk:8-jdk-alpine ARG JAR_FILEtarget/*.jar COPY ${JAR_FILE} app.jar ENTRYPOINT ["java","-jar","/app.jar","--server.port9090"]在A服务器上启动jenkins …

提示词工程(Prompt Engineering)的崛起——为什么“会写Prompt”成了新技能?

&#x1f380;【开场 猫猫狐狐的对话】&#x1f43e;猫猫扒着屏幕&#xff1a;“喵&#xff1f;咱写的这句 Prompt 怎么又跑偏啦&#xff1f;明明只是想让它帮忙写一段 Python 代码&#xff0c;它偏要给咱写论文摘要……” &#x1f98a;狐狐眯着眼&#xff0c;声音带点冷意&a…

供应链管理系统入门知识:是什么,功能模块,怎么定制开发?

如果你是刚接触企业运营的新手&#xff0c;听到 “供应链管理系统” 可能会觉得有点复杂。其实&#xff0c;它就像一个 “智能管家”&#xff0c;帮企业把从买材料到卖产品的一系列流程管得明明白白。今天就用大白话给你讲清楚这个系统到底是什么&#xff0c;以及它能帮上什么忙…

kotlin - 平板分屏,左右拖动,2个Activity计算宽度,使用ActivityOptions、Rect(三)

kotlin - 平板分屏&#xff0c;左右拖动&#xff0c;2个Activity计算宽度&#xff0c;使用ActivityOptions、Rect使用平板&#xff0c;api33才支持&#xff0c;可以左右拖动&#xff0c;分屏第一个页面 &#xff0c; 思考&#xff1a;分屏后&#xff0c;对整个app的影响&#x…

v0.29.3 敏感词性能优化之繁简体转换 opencc4j 优化

敏感词性能调优系列 v0.29.0 敏感词性能优化提升 14 倍全过程 v0.29.1 敏感词性能优化之内部类迭代器内部类 v0.29.2 敏感词性能优化之基本类型拆箱、装箱的进一步优化的尝试 v0.29.3 敏感词性能优化之繁简体转换 opencc4j 优化 背景 opencc4j opencc4j 中&#xff0c;因…

Spark SQL解析查询parquet格式Hive表获取分区字段和查询条件

首先说一下&#xff0c;这里解决的问题应用场景&#xff1a; sparksql处理Hive表数据时&#xff0c;判断加载的是否是分区表&#xff0c;以及分区表的字段有哪些&#xff1f;再进一步限制查询分区表必须指定分区&#xff1f; 这里涉及到两种情况&#xff1a;select SQL查询和…

谷歌发布文本嵌入模型EmbeddingGemma(附部署方式)

EmbeddingGemma是谷歌于2025年9月开源的开放式文本嵌入模型&#xff0c;专为端侧设备设计&#xff0c;具备以下核心优势&#xff1a; 性能优势 在MTEB基准测试中&#xff0c;EmbeddingGemma在500M以下参数规模的多语言文本嵌入模型中表现最佳&#xff0c;性能接近参数翻倍的顶…

CPU调度——调度的目标

2.2.2 调度的目标 当系统中“想运行”的实体多于 CPU 的数量时&#xff0c;调度就不可避免地要在“效率”与“公平”之间做取舍。直观地说&#xff0c;一类目标希望把硬件压榨到更高的利用率&#xff0c;让单位时间内做更多的工作&#xff1b;另一类目标则关心个体体验&#x…