ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Vue3零基础实战:一小时搭建AI监控系统前端页面

Vue3零基础实战:一小时搭建AI监控系统前端页面 这次我们来看一个 Vue3 零基础实战项目用一小时从空目录开始搭出一套 AI 监控系统的前端页面。先说明白这个项目里的 AI 推理不由前端完成真正的模型检测在服务端运行前端负责把监控画面、目标框、置信度、告警事件和统计报表整套可视化交互串起来。对零基础同学来说它的价值在于你不是在背 Vue3 的语法点而是跟着一条完整的业务主线把工程化开发走通。这套 AI 监控系统前端包含几个最核心的模块摄像头列表与设备状态、实时视频播放与检测框叠加、告警事件流、今日检测统计和异常趋势图表。技术上使用的是 Vue3 Vite Vue Router Pinia Axios 这条主流组合如果没有后端 AI 服务你还可以用 Mock 数据把页面流程完全跑通。这也是我推荐这个项目的原因它不挑机器不依赖 GPU普通开发电脑就能启动重点在前端工程能力的训练。本文会按真实开发顺序展开先装环境再建项目接着把路由、请求层、视频播放组件、告警模块、统计大屏逐个实现最后做生产构建和 Nginx 部署。每个步骤我都会给出可复制的代码和操作说明并标注哪些内容需要根据你自己的后端接口调整。文章末尾还放了常见问题排查表启动报错、跨域、路由 404 这类问题可以直接对照解决。1. AI监控系统前端项目核心能力速览在开始动手之前先把这套项目的规格放在前面方便你判断它适不适合现在的需求。下面的表格覆盖了项目类型、技术选型、启动方式、硬件门槛和接口能力每一项都是按一个可运行的 Vue3 前端工程来描述的没有夸张能力也不会给你画一个“前端跑 AI 模型”的大饼。能力项说明项目类型Vue3 前端实战项目AI 监控系统可视化平台核心业务监控设备管理、实时画面预览、目标检测结果标注、告警事件流、统计报表技术栈Vue3 Vite Vue Router Pinia Axios可扩展 Element Plus、ECharts、HLS.js启动方式npm install 安装依赖npm run dev 启动开发服务构建产物npm run build 生成静态文件可部署到 Nginx 或任意静态服务器数据来源后端 AI 平台接口没有后端时使用 Mock 数据硬件要求普通开发电脑即可无 GPU 需求API 能力使用 Axios 统一请求层后端可对接设备服务、告警服务、统计服务批量能力页面本身不做批量任务设备列表天然适合批量管理场景适合读者Vue3 零基础、前端入门、需要快速搭建监控或安防看板的开发者这里的关键定位是这是一个前端项目不是 AI 算法项目。目标检测、人脸识别、行为分析这类能力属于后端 AI 服务前端拿到的是检测结果坐标、类别、置信度等结构化数据。你在页面上看到的每一个绿色的目标框都来自后端接口的返回前端只负责渲染和交互。搞清楚这个边界后面的开发就不会混乱。2. 适用场景与使用边界这个项目最适合的场景有三类。第一类是 Vue3 初学者已经看完基础语法想找一个比 TodoList 更有业务感、比商城更贴近工业场景的项目练手第二类是需要在短时间内给公司或学校搭建监控可视化看板的开发者这套页面结构可以快速改造成内部安防大屏第三类是准备做毕设或简历项目的人AI 监控前端加上后端检测接口就是一个完整度很高的作品。它能解决的问题也很明确把散乱的摄像头设备、告警消息、统计数字集中到一个前端界面里让操作人员可以实时看到视频画面、检测结果和异常事件。前端不直接存储视频也不做算法推理负责的是“看”和“点”这两件事看是视频展示和告警展示点是设备切换、告警确认、时间筛选和图表联动。不适用场景也要提前说清楚。如果你想用这个项目直接跑 YOLO、训练模型、在浏览器里做实时检测那方向不对需要的是 Python 后端配合深度学习环境不是纯 Vue3 工程。另外如果你的摄像头是 RTSP 私有协议浏览器默认无法直接播放前端需要接转流服务或使用支持对应协议的播放器如果后端接口没有做好鉴权和限流前端也无法解决数据泄露问题。还有一条必须放在前面的提醒监控系统涉及摄像头画面、人脸信息和场所隐私任何时候接真实数据都要先确认授权。测试阶段建议使用模拟视频流和假告警数据不要拿真实办公区、宿舍、公共区域的人脸画面来做实验。正式上线前需要确认使用场景符合当地法律法规和平台规范并在界面上提供清晰的隐私提示和权限控制机制。3. 开发环境准备与前置条件这个项目对开发环境的要求不高但基础工具必须提前装好。整个链路依赖 Node.js、npm、一个现代浏览器和一个趁手的代码编辑器。下面按顺序检查每一项缺什么补什么。3.1 Node.js 与 npmVue3 Vite 的工程都跑在 Node.js 上所以第一个要装的是 Node.js。建议安装 LTS 版本Vite 5 以上通常要求 Node.js 18 或更高版本。装完之后打开终端执行下面的命令确认版本号node -v npm -v如果能正常输出版本号说明环境可用。如果提示命令找不到需要重新安装 Node.js并确认安装时加入了系统 PATH。Windows 用户安装后如果终端里还识别不了可以重启终端或重新打开一个新的命令窗口让环境变量生效。3.2 代码编辑器与浏览器编辑器强烈建议使用 VSCode配合 Vue 官方插件 Volar。Vue3 的单文件组件在 VSCode 里需要 Volar 提供语法高亮、模板补全和类型提示体验会比裸写编辑器好很多。安装方法很简单在 VSCode 扩展市场搜索 Volar安装后重启窗口即可。浏览器方面Chrome 或 Edge 都可以。监控页面涉及视频流播放和 WebSocket 长连接建议用较新的浏览器版本避免协议兼容问题。如果用了 HLS 播放 H.264 视频流还需要确认目标浏览器对 MSE 的支持。3.3 后端服务与接口依赖前端项目本身可以先用 Mock 数据跑通但如果要看到真实效果还需要一个提供接口的后端 AI 服务。常见的接口包括摄像头列表接口、目标检测结果接口、告警事件接口、统计汇总接口。这些接口可能由 Python FastAPI、Spring Boot、Node.js 或其他后端提供前端不关心实现语言只关心返回的数据格式。在项目起步阶段建议先和后端约定好统一的响应结构比如所有接口都返回{ code, message, data }这种格式。这样前端的 Axios 拦截器只需要处理一次响应解包后面加接口时改动最小。如果后端还没有开发完可以先在前端写死一份 Mock 数据等联调时再切换成真实接口。4. 项目初始化与前端框架搭建环境准备好了就进入正题。这里我会从零创建一个 Vite Vue3 项目然后安装路由、状态管理和请求库最后把目录结构设计成适合 AI 监控系统扩展的形态。4.1 创建 Vite 项目打开终端进入你准备存放代码的目录执行下面的命令。ai-monitor是项目名你可以按自己的习惯改npm create vitelatest ai-monitor -- --template vue cd ai-monitor npm install npm run dev执行完成后终端会输出一个本地访问地址默认是http://localhost:5173。浏览器打开这个地址如果能看到 Vite 默认的欢迎页说明项目创建成功。这里有一个常见问题如果你在非交互终端执行npm create vite可能会因为提示交互而卡住这时候可以加上--template vue参数跳过选择项直接生成 Vue3 模板。4.2 安装业务依赖基础模板只包含 Vue 本身我们需要再装几个项目运行时要用的库。路由负责页面跳转Pinia 负责全局状态Axios 负责请求后端接口。如果你要用组件库和图表可以顺便把 Element Plus、ECharts 一起装上。视频播放方面如果后端提供 HLS 格式的视频流还需要 HLS.js。npm install vue-router4 pinia axios npm install element-plus element-plus/icons-vue npm install echarts npm install hls.js版本说明一下Vue3 对应的路由是 4.x 版本状态管理用 Pinia这两个是最主流的组合。Element Plus 和 ECharts 不是必须的但在这个监控项目中能省很多事比如表格、弹窗、下拉选择直接用现成组件图表用 ECharts 画折线图和柱状图。4.3 规划目录结构项目创建后src目录默认很简洁。为了后面维护方便我建议按功能模块重构一下目录。下面这个结构对监控系统比较合适也符合大多数 Vue3 中后台项目的习惯ai-monitor/ ├── .env.development ├── .env.production ├── index.html ├── package.json ├── vite.config.js └── src/ ├── main.js ├── App.vue ├── router/ │ └── index.js ├── store/ │ └── device.js ├── api/ │ ├── request.js │ ├── device.js │ ├── alarm.js │ └── statistics.js ├── views/ │ ├── Dashboard.vue │ ├── CameraList.vue │ ├── CameraPlayer.vue │ ├── AlarmList.vue │ └── Statistics.vue ├── components/ │ ├── VideoPlayer.vue │ ├── DetectOverlay.vue │ ├── AlarmCard.vue │ └── StatChart.vue └── utils/ └── format.jsviews放页面级组件components放可复用组件api按业务模块拆接口文件store放设备切换等全局状态。这套结构是典型的前后端分离前端工程后续加需求时按模块新增文件就行不会出现一个几百行组件撑爆所有逻辑的情况。4.4 配置环境变量与开发代理前端项目在开发阶段最常见的坑是跨域。Vite 开发服务器可以配置代理把/api开头的请求转发到后端服务这样浏览器就不会直接跨域访问后端。新建.env.development文件写入以下内容VITE_API_BASE_URL/api VITE_WS_URLws://localhost:8080/ws/alarm然后在vite.config.js里配置代理import { defineConfig } from vite import vue from vitejs/plugin-vue export default defineConfig({ plugins: [vue()], server: { host: 0.0.0.0, port: 5173, proxy: { /api: { target: http://localhost:8080, changeOrigin: true } } } })这里的前提是后端服务跑在localhost:8080而且接口路径都带/api前缀。如果你的后端地址或前缀不一样对应修改target和proxy里的键名即可。生产环境不走 Vite 代理需要使用 Nginx 做反向代理第 7 章会单独讲。5. 核心功能实现从监控列表到统计大屏目录搭好之后开始写页面。这一章按业务顺序讲解核心模块的实现思路每个模块都会给出关键代码但不追求把整个项目源码粘贴过来重点是让你理解每个页面在做什么、数据从哪来、组件之间怎么配合。5.1 路由与整体布局监控系统是一个典型的“左侧菜单 右侧内容”的后台布局。先安装路由并定义页面路径。下面是一个基础的router/index.jsimport { createRouter, createWebHistory } from vue-router const routes [ { path: /, component: () import(../views/Dashboard.vue) }, { path: /cameras, component: () import(../views/CameraList.vue) }, { path: /player, component: () import(../views/CameraPlayer.vue) }, { path: /alarms, component: () import(../views/AlarmList.vue) }, { path: /statistics, component: () import(../views/Statistics.vue) } ] const router createRouter({ history: createWebHistory(), routes }) export default router这里使用createWebHistory也就是 HTML5 History 模式URL 里没有#更清爽。但这个模式有一个后续部署要注意的坑后端必须把不存在的路径回退到index.html否则刷新/statistics页面会 404。开发阶段 Vite 会自动处理生产环境需要在 Nginx 里配置。在main.js中挂载路由和 Piniaimport { createApp } from vue import { createPinia } from pinia import App from ./App.vue import router from ./router import ElementPlus from element-plus import element-plus/dist/index.css const app createApp(App) app.use(createPinia()) app.use(router) app.use(ElementPlus) app.mount(#app)布局部分可以在App.vue里用 Element Plus 的el-container搭一个最简单的外框左侧是摄像头列表菜单右侧是路由出口。这里不展开所有样式代码但你要记住一个原则布局组件只负责布局不写业务逻辑具体数据放到对应的 view 组件里。5.2 Pinia 状态管理设备列表与当前选中设备监控页面之间经常需要共享状态。比如用户在左侧点击一个摄像头右侧的视频播放器和告警列表要立刻切换到对应设备。如果每个页面各自请求一次设备列表不仅冗余而且切换设备时状态不同步。比较好的做法是用 Pinia 管理设备列表和当前选中的设备。新建store/device.jsimport { defineStore } from pinia import { getCameraList } from ../api/device export const useDeviceStore defineStore(device, { state: () ({ cameraList: [], currentCamera: null, loading: false }), actions: { async fetchCameraList() { this.loading true try { const res await getCameraList() this.cameraList res.data || [] } finally { this.loading false } }, selectCamera(camera) { this.currentCamera camera } } })这里把设备相关的操作收敛到了一个 store 中。页面组件只需要调用deviceStore.cameraList渲染列表点击时调用selectCamera更新当前设备视频播放器和告警组件都能响应变化。这种方式比props逐层传递清晰很多也是 Vue3 中大型页面推荐的协作方式。5.3 实时视频组件与检测框叠加视频播放是监控系统的视觉核心。真实监控项目一般不会直接把 RTSP 地址给前端而是通过后端或流媒体服务转成 HLS、FLV、WebRTC 等浏览器可播放的协议。下面这个VideoPlayer.vue做了一个通用的 HLS 播放示例并且支持在视频上方叠加检测框。template div classvideo-player video refvideoRef autoplay controls muted/video div classdetect-overlay div v-forbox in boxes :keybox.id classdetect-box :styleboxStyle(box) span{{ box.label }} {{ box.confidence }}/span /div /div /div /template script setup import { ref, onMounted, onUnmounted } from vue import Hls from hls.js const props defineProps({ url: { type: String, required: true }, boxes: { type: Array, default: () [] } }) const videoRef ref(null) let hls null function boxStyle(box) { return { left: ${box.x}%, top: ${box.y}%, width: ${box.w}%, height: ${box.h}% } } onMounted(() { const video videoRef.value if (!video) return if (Hls.isSupported() /\.m3u8/.test(props.url)) { hls new Hls() hls.loadSource(props.url) hls.attachMedia(video) } else { video.src props.url } }) onUnmounted(() { if (hls) { hls.destroy() } }) /script检测框坐标来自后端字段统一使用百分比位置也就是x、y、w、h都代表相对画面的比例。这样无论视频分辨率是多少前端都不用做像素换算直接给目标框设置对应的百分比样式就可以对齐画面。boxes数据可以由父组件定时轮询接口更新也可以通过 WebSocket 实时推送更新。这个组件的设计思路是“播放器只做播放业务方自己决定传什么视频流和什么检测框”。如果你要接其他协议只需要在onMounted里增加对应的播放器初始化逻辑不需要改动外层业务代码。5.4 告警列表与自动刷新告警列表展示 AI 检测到的异常事件比如人员闯入、区域入侵、未佩戴安全帽等。列表项一般包含告警时间、设备名称、事件类型、截图和确认状态。首页的告警列表需要保持实时性常见方案有两种轮询和 WebSocket。先看轮询方案简单可靠适合列表数据量不大的场景。在组件挂载后定时拉取最新告警import { ref, onMounted, onUnmounted } from vue import { getAlarmList } from ../api/alarm const alarmList ref([]) let timer null async function loadAlarms() { const res await getAlarmList({ page: 1, pageSize: 20 }) alarmList.value res.data || [] } onMounted(() { loadAlarms() timer setInterval(loadAlarms, 5000) }) onUnmounted(() { clearInterval(timer) })这段代码的核心是onMounted里启动定时器onUnmounted里清理定时器避免组件销毁后请求还在跑。定时器的间隔要根据实际业务量调整如果告警频率极高5 秒一次可能太慢可以换成 WebSocket 推送如果只是演示可以拉长到 10 秒减轻服务端压力。5.5 统计图表大屏数据大屏是监控系统的点睛之笔。常见图表包括今日检测总数、各类别检测占比、时间段异常趋势、设备在线率。这里用 ECharts 画一个异常趋势折线图先定义图表容器template div refchartRef classchart/div /template script setup import { ref, onMounted, onUnmounted } from vue import * as echarts from echarts const chartRef ref(null) let chart null onMounted(() { chart echarts.init(chartRef.value) chart.setOption({ xAxis: { type: category, data: [00:00, 06:00, 12:00, 18:00, 23:00] }, yAxis: { type: value }, series: [ { type: line, data: [12, 28, 45, 63, 30] } ] }) }) onUnmounted(() { if (chart) { chart.dispose() } }) /script这是一个最简示例。真实项目中图表数据应该由统计接口返回并且在窗口尺寸改变时调用chart.resize()。使用 ECharts 要注意组件卸载时一定要执行dispose否则会报There is a chart instance already initialized on the dom的错误。如果图表在一个页面里用多个实例可以把初始化逻辑封装成一个自定义组件按数据维度传入配置项。6. 接口 API 对接与 Mock 数据切换前面的页面代码里已经调用了getCameraList、getAlarmList这类接口函数。这一章把接口层完整讲清楚包括统一的 Axios 封装、接口定义方式、WebSocket 实时通道以及没有后端时怎么用 Mock 数据继续开发。6.1 接口路径约定为了方便说明下面的接口路径都是示例实际开发时以后端接口文档为准业务方法路径说明摄像头列表GET/api/camera/list返回所有可用摄像头检测框数据GET/api/camera/detect获取某个摄像头最新检测结果告警列表GET/api/alarm/list分页获取告警记录告警确认PUT/api/alarm/confirm确认一条告警统计汇总GET/api/statistics/overview获取今日总览数据告警推送WS/ws/alarm服务端推送实时告警前端可以按业务模块拆分文件。比如api/device.js只放设备相关接口api/alarm.js只放告警相关接口这样接口变动时定位成本和回归成本都比较低。6.2 Axios 请求层封装Axios 封装的核心目标是统一处理 baseURL、超时时间、鉴权头和响应解包。直接看api/request.js的示例import axios from axios const service axios.create({ baseURL: import.meta.env.VITE_API_BASE_URL, timeout: 10000 }) service.interceptors.request.use((config) { const token localStorage.getItem(token) if (token) { config.headers.Authorization Bearer ${token} } return config }) service.interceptors.response.use( (response) { const res response.data if (res.code ! 0) { console.error([api error], res.message) return Promise.reject(new Error(res.message)) } return res }, (error) { console.error([request error], error) return Promise.reject(error) } ) export default service这里假定后端统一返回{ code, message, data }code为 0 表示成功。如果你的后端不是这个结构只需要修改响应拦截器里的判断逻辑。使用import.meta.env.VITE_API_BASE_URL是为了读取环境变量开发环境是/api走 Vite 代理生产环境可以改为后端的完整域名或 Nginx 的代理路径。再以设备接口为例封装对应的请求函数import request from ./request export function getCameraList(params) { return request({ url: /camera/list, method: get, params }) } export function getCameraDetect(cameraId) { return request({ url: /camera/detect, method: get, params: { cameraId } }) }调用时直接用getCameraList()即可。这里有一个容易踩的坑如果在响应拦截器中已经返回了res调用方接收到的就是整个响应对象后续访问数据要写res.data如果拦截器直接返回res.data调用方拿到的就是业务数据。两种习惯都常见但团队内要保持一致。6.3 WebSocket 实时告警通道告警列表需要实时刷新WebSocket 比轮询更高效。Pinia 里可以单独维护一个连接状态在应用启动时建立连接收到告警消息后更新列表。下面给出一个通用模板let ws null export function connectAlarmSocket(onMessage) { const url import.meta.env.VITE_WS_URL ws new WebSocket(url) ws.onopen () { console.log([ws] connected) } ws.onmessage (event) { try { const data JSON.parse(event.data) onMessage(data) } catch (error) { console.error([ws] parse error, error) } } ws.onclose () { console.log([ws] closed) } return ws }使用 WebSocket 时要注意心跳机制。如果网络中有代理或负载均衡器空闲连接可能被断开前端需要在定时器里发送心跳消息并监听onclose后自动重连。这个逻辑对监控系统非常重要因为告警推送是核心能力连接断了必须恢复不能等到用户刷新页面才重新建立。6.4 Mock 数据切换方案后端接口还没有开发完成时前端可以用 Mock 数据先跑通页面。最简单的做法是写一个mock开关根据环境变量切换数据来源。比如在.env.development中增加VITE_USE_MOCKtrue然后在请求层里判断const enableMock import.meta.env.VITE_USE_MOCK true export function getCameraList(params) { if (enableMock) { return Promise.resolve({ code: 0, data: [ { id: 1, name: 东门摄像头, status: online, url: https://example.com/live.m3u8 }, { id: 2, name: 仓库入口, status: online, url: https://example.com/live2.m3u8 } ] }) } return request({ url: /camera/list, method: get, params }) }Mock 数据的价值在于让前端开发不受后端进度影响页面效果和接口联调可以并行推进。等后端接口可用后把VITE_USE_MOCK改成false或移除判断逻辑就能无缝切到真实接口。7. 生产构建与 Nginx 部署开发完成后项目需要打包成静态文件并部署到服务器。这一步不需要 GPU也不需要 Node 持续运行构建产物就是一堆静态资源由 Nginx 托管即可。7.1 生产构建执行打包命令npm run build构建完成后项目根目录会生成dist文件夹。里面是编译压缩后的 HTML、CSS、JS 文件和静态资源。部署时只需要把dist的内容上传到服务器的 Web 根目录。如果项目使用了环境变量构建和部署时要确认.env.production配置正确。比如生产环境的后端地址可能不是/api而是https://monitor.example.com/api这时配置要写成完整域名。Nginx 可以通过location /api反向代理到后端服务也可以直接让前端请求完整域名两种方式按实际部署环境选择。7.2 Nginx 配置示例一个典型的单页应用部署配置如下server { listen 80; server_name monitor.example.com; root /usr/share/nginx/html; index index.html; location / { try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }try_files $uri $uri/ /index.html是这里最关键的一行。它的作用是当请求路径不是真实文件时把请求回退到index.html。没有这一行前端路由使用 HTML5 History 模式时刷新/cameras或/statistics就会返回 404。/api/的 location 负责把前端请求转发到后端服务避免浏览器跨域。7.3 部署后的常见问题部署后如果接口请求失败最优先检查 Nginx 的proxy_pass地址是否正确以及后端服务是否正常运行。打开浏览器控制台看网络请求实际发到了哪个地址、返回了什么状态码。如果页面能打开但刷新子路由后出现 404说明try_files那行配置可能被注释掉了或者 Nginx 配置没有重新加载。修改配置后执行nginx -t检查语法再用nginx -s reload重新加载配置。8. 常见问题与排查方法前端项目跑不起来或者运行效果不对时问题往往集中在几个固定的环节。下面的排查表总结了最常见的现象、原因和解决思路建议先收藏遇到问题时逐行对照。问题现象可能原因排查方式解决方案npm install 安装失败网络原因或 npm 源缓慢查看终端错误信息切换到国内镜像源后重新安装npm run dev 无法启动Vite 版本与 Node 版本不兼容执行 node -v 和 npm -v 查看版本升级 Node 到 LTS 版或降低 Vite 版本启动后页面打不开端口被占用或服务未启动检查终端输出和端口监听情况修改 vite.config.js 的 port 或关闭占用进程跨域请求失败后端未开启 CORS或代理配置错误浏览器 Network 面板查看请求地址配置 Vite proxy或让后端开启 CORS视频画面黑屏视频流协议不被浏览器支持查看播放器控制台和流地址格式使用 HLS.js、flv.js 或转流服务检测框位置不对坐标单位不是百分比对比后端返回的坐标和画面像素统一约定为百分比坐标并校验换算逻辑路由刷新后 404Nginx 没有配置 try_files刷新子路由并观察请求路径在 Nginx location 中添加 try_files 规则WebSocket 连接中断代理超时或连接空闲查看浏览器 Application 面板的 WS 状态增加心跳消息和断线重连逻辑接口数据为空响应结构不一致或拦截器解包错误在 Network 面板查看原始响应调整 Axios 响应拦截器统一响应结构排查的通用思路是先在浏览器开发者工具里看 Network 面板和 Console 面板确认请求有没有发出去、返回了什么、页面脚本有没有报错。很多问题在报错信息里其实已经给出明确提示比如“端口被占用”“module not found”“Cannot read properties of undefined”等直接按提示定位就行。如果你是 Windows 用户启动时还可能遇到系统终端权限导致的执行策略问题。比如执行npm run dev时提示脚本不能运行可以用Set-ExecutionPolicy -Scope CurrentUser RemoteSigned调整 PowerShell 执行策略或改用管理员身份打开终端。注意这只是让本地脚本可以运行不影响项目代码本身。9. 最佳实践与开发建议把项目跑通只是第一步真正让这个 AI 监控系统变得可维护、可扩展、可用于生产需要养成几个习惯。9.1 组件拆分要按业务边界而不是按标签视频播放器、告警卡片、统计图表这类的复用组件应该只关心自己的输入输出不直接请求接口。比如VideoPlayer.vue通过 props 接收视频地址和检测框数组由父组件决定数据从哪来。这样后期换数据源、换接口都只改父组件播放器本身不需要动。反过来页面组件不应该塞入大量没有复用的 DOM 结构和样式。如果你发现在一个页面里写了超过 400 行模板或者一个组件同时承担了十几个职责就需要考虑拆原子组件了。拆分的原则很简单同一段 UI 和逻辑在未来可能被另一个页面复用时就拆出去。9.2 实时数据渲染要控制频率监控页面里最常见的性能问题是高频更新导致页面卡顿。告警列表如果每 5 秒刷新一次同时统计图表每 5 秒重新渲染一次数据量大时浏览器会持续高负载。建议对不同模块用不同的更新频率视频检测框可以依赖后端推送告警列表用页面可见时才刷新统计图表做成手动刷新或定时器频率更低。如果后端推送的数据量非常大比如一秒钟产生几十条检测结果前端还需要做节流或批量更新。最简单的方式是使用requestAnimationFrame合并同一帧内的多次数据更新或者在组件里维护一个队列定时批量替换检测框数组。这样既保证实时性又不会让渲染线程被大量setState打垮。9.3 安全合规建议监控系统的安全底线比普通项目高。开发和测试阶段尽量使用模拟数据不要直接接入真实场景的人脸、车辆、人员轨迹等隐私数据。接口层需要对后端返回的数据做基本校验避免异常值直接渲染到页面上。部署上线后页面需要支持用户登录和权限控制至少区分“只读查看”和“可操作告警”两类角色。摄像头列表、告警截图、实时画面都属于敏感数据前端不应在浏览器 localStorage 中长期保存 token接口必须支持 token 失效后的重新认证。涉及真实监控场景还需要在明显位置提示用户该区域正在被监控并按照相关隐私保护要求处理数据留存期限和访问日志。9.4 后续可扩展方向这个架构可以继续扩展的方向很多。如果想接入真实检测结果可以增加一个后端 AI 服务模块目标检测结果通过消息队列推送给前端如果你想做多级组织架构可以给摄像头列表增加分组的树形结构如果摄像头数量变多需要在设备列表中做分页、关键字搜索和在线状态筛选。统计层面可以增加更多图表比如实时检测次数热力图、各类型告警占比饼图、设备在线时长趋势。操作层面可以增加告警截图预览、告警导出 Excel、一键确认多条告警等功能。这些扩展都不需要改动底层目录结构按业务模块新增页面和接口文件即可。10. 总结与下一步这套 Vue3 AI 监控系统前端项目本质上是用一个接近真实业务的场景把环境搭建、工程初始化、路由、状态管理、请求封装、视频播放、实时刷新、图表展示和部署发布整个链路完整串联起来。它最值得尝试的点在于你可以不依赖后端、不依赖 GPU、不依赖真实摄像头数据先在本地把一套完整的监控可视化平台跑起来后面再接真实接口时只需要替换数据源。建议第一次运行时的验证顺序是先启动项目看到默认页面再接入 Mock 数据检查摄像头列表和告警列表最后接视频流测试播放和检测框叠加。最容易踩的坑是跨域和路由 404这两个问题在 Vite 和 Nginx 配置里都有对应解法。如果做出来后想继续深入下一步可以从前端扩展到后端 AI 服务比如对接目标检测模型、把检测结果通过 WebSocket 推送到这个前端界面。到这里一套“前端可视化 后端检测”的 AI 监控系统就有了完整形态。代码结构已经替你把模块边界划清楚了打开终端先跑一条npm create vite剩下的事情就容易了。建议收藏备用后面要用的时候直接照流程走。
返回列表