新闻详情

新闻详情

首页 / 资讯中心 / 详情

Vue3实战:从零搭建AI监控系统前端与检测后端

发布时间:2026/9/3 18:23:24来源:尧图网络
Vue3实战:从零搭建AI监控系统前端与检测后端
大家平时写 Vue 项目最头疼的就是两件事一是环境搭到一半各种报错网上教程版本又老又碎二是语法刚学会不知道怎么做一个能真正跑起来的项目。这篇文章会从零开始用尽量短的时间带你完成三件事搭好 Vue3 开发环境、掌握 Vue3 最常用的核心语法、手写一个带 AI 检测能力的监控系统前端。这个实战项目不是简单的计数器或者 TodoList而是一个能看视频画面、能显示 AI 检测告警、能统计告警数据的完整系统。后端部分我们也会用 Python 写一个轻量级图像检测服务让整个链路真正跑通。零基础可以跟着一步步做有基础的可以直接跳到后面的实战章节复用代码。需要提醒的是本文涉及的前后端代码都以“能跑通、能看懂、能扩展”为目标不会引入太重型的架构。正式项目里你可以在它的基础上接更完整的后端、数据库和消息推送。1. Vue3 到底是什么为什么学它1.1 Vue3 解决了什么问题Vue 是一个用于构建用户界面的渐进式 JavaScript 框架。所谓“渐进式”意思是你可以只在页面里的某个局部使用它也可以用全家桶开发一个完整的前后端分离项目。Vue3 是 Vue 目前的主流大版本。相比 Vue2它最大的变化是引入了组合式 APIComposition API同时也保留了对 Vue2 选项式 APIOptions API的兼容。组合式 API 的核心好处是同一个功能的代码可以放在一起不再像以前那样必须分散在 data、methods、computed 等固定区块里。项目变大以后维护性会好很多。Vue3 在底层还重写了响应式系统使用 Proxy 取代了 Vue2 的 Object.defineProperty这带来两个直接好处响应式数据可以监听新增属性、删除属性和数组下标变化。大型数据对象上的性能得到提升。另外Vue3 对 TypeScript 的支持非常友好代码提示和类型推导比 Vue2 时代强了一个量级。目前主流的新项目中Vue3 Vite TypeScript 已经成为很常见的组合。1.2 为什么选择“AI 监控系统”作为实战项目很多 Vue3 教程一上来就是购物车、后台管理、待办事项这些项目作为练手当然可以但离真实业务有一定距离。AI 监控系统是一个覆盖面很广的场景它天然包含几个前端常用能力页面路由与多页面切换。视频流或图片流的展示。实时告警列表的渲染。数据统计与图表展示。前端与后端的接口交互。从技术角度看这个项目能把你学到的基础语法、组件通信、状态管理、网络请求全部串起来而不是一个个孤立的知识点。因为输入标题和关键词中都出现了“pytorch 环境搭建”“yolov5 模型训练环境搭建”这类热词这里需要说明一下真正训练 YOLOv5 模型涉及深度学习环境和数据集制作不是 1 小时能完成的。本文的实战部分为了遵守“极简速通”的定位会先做一个基于 OpenCV 的轻量级检测演示使用的也是 CPU 也能跑的通用的目标检测模型方式。学习到项目后半段如果大家对深度学习模型训练感兴趣可以顺着这个思路去研究 YOLOv5 或更轻量级的检测方案。2. 环境搭建30 分钟搞定开发环境2.1 安装 Node.js 与 npmVue3 项目依赖 Node.js 环境。npm 是 Node.js 自带的包管理器用来下载和管理第三方依赖。打开终端Windows 推荐 PowerShell 或 CMDmacOS 推荐 Terminal输入下面命令检查是否已经安装node -v npm -v如果提示命令不存在需要先去 Node.js 官网下载 LTS 版本安装。安装完成后重新打开终端再次执行上面两条命令能看到版本号就说明环境就绪。这里不写死具体版本因为 Node.js 版本迭代较快。原则上使用 LTS长期支持版本即可Vue3 和 Vite 对 Node 的版本要求会有变化建议 Node 版本不低于 16.14如果你用的是 Vite 5则建议 Node 版本不低于 18。2.2 使用官方脚手架创建 Vue3 项目Vue 官方提供了一个脚手架工具create-vue它是目前创建 Vue3 项目最推荐的方式。你不需要手动安装它直接用 npm 调用即可。在终端中执行npm create vuelatest执行后终端会交互式地询问你要不要启用 TypeScript、Vue Router、Pinia 等特性。这里我给出一份适合本项目的选择Project name: ai-monitor-frontend Add TypeScript? No Add JSX Support? No Add Vue Router for Single Page Application? Yes Add Pinia for state management? Yes Add Vitest for Unit Testing? No Add an End-to-End Testing Solution? No Add ESLint for code quality? Yes说明为了降低零基础同学的阅读门槛这里没有启用 TypeScript。实际项目我非常推荐使用 TypeScript但本文示例以 JavaScript 为主保证最短路径跑通。创建完成后进入项目目录并安装依赖cd ai-monitor-frontend npm install最后启动开发服务器npm run dev终端会输出一个本地访问地址默认是http://localhost:5173在浏览器打开如果能看到 Vue 的欢迎页面就说明项目创建成功。2.3 项目目录结构解读刚创建的项目目录长这样ai-monitor-frontend/ ├── .vscode/ ├── public/ ├── src/ │ ├── assets/ │ ├── components/ │ ├── router/ │ ├── stores/ │ ├── views/ │ ├── App.vue │ └── main.js ├── .eslintrc.cjs ├── index.html ├── package.json └── vite.config.js其中重点需要关注的是src目录main.js项目入口负责创建 Vue 实例并挂载到页面。App.vue根组件整个应用的入口组件。router存放路由配置文件。storesPinia 状态管理文件。views页面级组件对应不同的路由页面。components可复用的业务组件。后面实战部分我们会主要在这些目录中新增和修改文件。2.4 编码工具推荐写 Vue 项目目前体验比较好的是 VS Code。建议安装下面两个插件Vue - Official原 VolarVue 单文件组件语法高亮和代码提示。ESLint配合项目里的 ESLint 配置实时提示代码问题。如果之前安装过 VeturVue2 时代的插件建议在 Vue3 项目中禁用掉否则可能出现语法提示冲突。3. Vue3 核心语法 15 分钟速通3.1 setup 语法糖与组合式 APIVue3 使用script setup语法糖后一个单文件组件SFC可以写得很简洁。它是组合式 API 的编译优化形式变量、函数、组件引入后都可以直接在模板中使用。来看一个最简单的组件示例template div p{{ message }}/p button clickhandleClick点击/button /div /template script setup const message Hello Vue3 function handleClick() { console.log(按钮被点击了) } /script注意script setup里定义的变量和函数不需要 return模板可以直接访问这是和普通script写法最大的区别。如果你的组件还需要定义组件名称或者做一些仅在普通 script 中支持的配置可以额外再加一个普通的script块这个后文实战中会用到。3.2 ref 与 reactive响应式数据响应式是 Vue 的核心能力。在组合式 API 中我们主要用ref和reactive创建响应式数据。ref可以包裹任意类型数据在 script 中读写需要加.value在模板中会自动解包。reactive只能包裹对象读写时不需要.value但不支持直接重新赋值整个对象。template div p计数{{ count }}/p p用户{{ user.name }}/p button clickincrement增加/button button clickupdateUser改名/button /div /template script setup import { ref, reactive } from vue const count ref(0) const user reactive({ name: 张三, age: 20 }) function increment() { count.value } function updateUser() { user.name 李四 } /script需要记住一个原则基本类型和数组、字符串这类数据优先用ref嵌套层级深的业务对象用它来维护整体数据模型会方便一些。reactive适合用对象包裹一组关联数据比如表单数据。3.3 computed 计算属性与 watch 监听computed用来声明一个依赖响应式数据、且可以自动更新的派生值。它最大的特点是只有依赖的值变化时才会重新计算并且计算结果会缓存。script setup import { ref, computed } from vue const price ref(100) const count ref(3) const totalPrice computed(() price.value * count.value) /script模板中你可以直接使用totalPrice只要price或count变化totalPrice会同步更新。watch用来监听响应式数据的变化执行副作用操作比如接口请求、DOM 操作、日志输出。script setup import { ref, watch } from vue const keyword ref() watch(keyword, (newValue, oldValue) { console.log(搜索关键词变化:, newValue, oldValue) }) /script如果监听的是reactive对象里的某个属性需要写成watch(() user.name, (newValue, oldValue) { console.log(newValue, oldValue) })注意这里不能用watch(user.name, ...)因为user.name不是一个响应式引用。computed和watch也是面试里经常被问到的知识点理解它们的区别很重要computed用于计算值watch用于观察变化。3.4 vue-router 路由与 Pinia 状态管理Vue 项目中页面之间的跳转由 vue-router 负责。创建项目时我们开启了 Vue Router路由配置在src/router/index.js中。路由文件的基本结构如下import { createRouter, createWebHistory } from vue-router import MonitorView from ../views/MonitorView.vue const router createRouter({ history: createWebHistory(), routes: [ { path: /, name: monitor, component: MonitorView } ] }) export default router在页面中使用router-link做页面跳转使用router-view显示当前路由对应的组件。Pinia 是 Vue3 官方推荐的状态管理库。当多个组件需要共享同一份数据时比如用户信息、告警列表就可以把它放进 Pinia。一个最简单的 store 长这样import { defineStore } from pinia import { ref } from vue export const useAlertStore defineStore(alert, () { const alertList ref([]) function addAlert(alert) { alertList.value.unshift(alert) } return { alertList, addAlert } })组件中使用时script setup import { useAlertStore } from ../stores/alert const alertStore useAlertStore() /script这样任何组件里通过alertStore.alertList读到的是同一份数据修改它也会同步到其他组件。3.5 组件通信props / emit父子组件之间通信遵循单向数据流父组件通过props传数据给子组件子组件通过emit触发事件通知父组件。子组件示例AlertCard.vuetemplate div classalert-card p{{ title }}/p button clickhandleConfirm确认/button /div /template script setup const props defineProps({ title: { type: String, default: } }) const emit defineEmits([confirm]) function handleConfirm() { emit(confirm, props.title) } /script父组件中使用template AlertCard title检测到人员入侵 confirmonConfirm / /template script setup import AlertCard from ../components/AlertCard.vue function onConfirm(title) { console.log(确认告警, title) } /script这套通信机制理解以后Vue3 开发的基本功就打牢了。接下来进入实战环节。4. 实战AI 监控系统前端实现4.1 项目规划与页面设计AI 监控系统前端规划以下三个页面实时监控页展示摄像头画面和 AI 检测结果。告警中心页展示历史告警记录支持状态筛选。数据统计页展示今日告警总数、处理率、趋势。实际项目中这三个功能通常对应一个中大型后台系统但对学习而言我们只保留必要的业务逻辑把复杂度控制在可接受范围内同时尽量贴近真实工程结构。整体技术栈如下Vue 3.4Vite 5Vue Router 4PiniaAxios用于请求后端接口Element PlusUI 组件库用来快速搭建告警表格和统计卡片4.2 安装额外依赖进入项目目录安装 Axios 和 Element Plusnpm install axios element-plus然后在src/main.js中引入 Element Plus 样式import { createApp } from vue import { createPinia } from pinia import ElementPlus from element-plus import element-plus/dist/index.css import App from ./App.vue import router from ./router const app createApp(App) app.use(createPinia()) app.use(router) app.use(ElementPlus) app.mount(#app)4.3 视频监控页接入实时画面实时监控页的核心思路是后端通过 MJPEG 流持续推送检测后的视频帧前端直接使用img标签加载该视频流地址。这样实现最简单也方便看到 AI 检测框的绘制效果。新建/src/views/MonitorView.vuetemplate div classmonitor-page h2实时监控/h2 div classmonitor-panel div classvideo-wrap img :srcvideoStreamUrl alt实时视频流 classvideo-img / div classstatus-tag {{ isConnected ? 检测中 : 连接中... }} /div /div div classmonitor-side h3最新告警/h3 el-empty v-ifalertStore.alertList.length 0 description暂无告警 / div v-foritem in alertStore.alertList.slice(0, 5) :keyitem.id classalert-item span classalert-type{{ item.type }}/span span classalert-time{{ item.time }}/span /div /div /div /div /template script setup import { ref, onMounted, onUnmounted } from vue import { useAlertStore } from ../stores/alert const videoStreamUrl ref(/api/video_feed) const isConnected ref(false) const alertStore useAlertStore() let timer null function fetchLatestAlert() { fetch(/api/latest_alert) .then((res) res.json()) .then((data) { if (data data.message) { alertStore.addAlert({ id: data.id, type: data.message, time: new Date().toLocaleTimeString() }) isConnected.value true } }) .catch(() { isConnected.value false }) } onMounted(() { timer setInterval(fetchLatestAlert, 3000) }) onUnmounted(() { clearInterval(timer) }) /script style scoped .monitor-page { padding: 20px; } .monitor-panel { display: flex; gap: 20px; margin-top: 16px; } .video-wrap { flex: 1; position: relative; border-radius: 8px; overflow: hidden; background: #000; min-height: 400px; } .video-img { width: 100%; height: auto; display: block; } .status-tag { position: absolute; top: 12px; right: 12px; background: rgba(0, 0, 0, 0.6); color: #fff; font-size: 12px; padding: 4px 10px; border-radius: 4px; } .monitor-side { width: 320px; border: 1px solid #eee; border-radius: 8px; padding: 16px; } .alert-item { display: flex; justify-content: space-between; padding: 8px 0; border-bottom: 1px dashed #f0f0f0; } .alert-type { color: #e6a23c; } .alert-time { color: #999; font-size: 12px; } /style这里需要注意两点第一videoStreamUrl直接写成了/api/video_feed所以前端开发服务器需要配置代理把/api开头的请求转发到后端服务。第二告警轮询使用setInterval每 3 秒请求一次真实生产环境通常会使用 WebSocket 推送这里用轮询是为了简化逻辑。在vite.config.js中配置代理让前端开发服务器把/api转发到http://localhost:5000import { fileURLToPath, URL } from node:url import { defineConfig } from vite import vue from vitejs/plugin-vue export default defineConfig({ plugins: [vue()], resolve: { alias: { : fileURLToPath(new URL(./src, import.meta.url)) } }, server: { proxy: { /api: { target: http://localhost:5000, changeOrigin: true } } } })4.4 告警中心展示 AI 检测结果告警中心页面主要展示历史告警记录。为了快速演示我们先用假数据填充等后端接口完成后可以替换成真实接口。新建/src/views/AlertCenterView.vuetemplate div classalert-center h2告警中心/h2 el-card el-table :datafilteredAlerts stripe el-table-column propid labelID width80 / el-table-column proptype label告警类型 width160 / el-table-column proptime label告警时间 width200 / el-table-column propdesc label描述 / el-table-column label状态 width120 template #default{ row } el-tag :typerow.status 未处理 ? danger : success {{ row.status }} /el-tag /template /el-table-column el-table-column label操作 width120 template #default{ row } el-button sizesmall clickmarkHandled(row) 标记处理 /el-button /template /el-table-column /el-table /el-card /div /template script setup import { ref, computed } from vue const alerts ref([ { id: 1, type: 人员入侵, time: 2025-01-10 10:12:00, desc: A区大门出现人员逗留, status: 未处理 }, { id: 2, type: 车辆异常, time: 2025-01-10 10:05:00, desc: B区停车场车辆停留过久, status: 未处理 }, { id: 3, type: 火焰检测, time: 2025-01-10 09:50:00, desc: C区仓库边缘出现烟雾, status: 已处理 } ]) const filteredAlerts computed(() alerts.value) function markHandled(row) { row.status 已处理 } /script这里使用ElTable结合computed展示数据是后台管理系统中最常见的写法。真实项目中告警数据通常会从后端接口获取并需要考虑分页和筛选这些内容适合在掌握基础后继续深入。4.5 数据统计使用 Pinia 管理全局状态数据统计页展示监控系统的运行概况。这一步顺手演示 Pinia 的实际玩法。先新建/src/stores/alert.jsimport { defineStore } from pinia import { ref } from vue export const useAlertStore defineStore(alert, () { const alertList ref([]) const totalCount ref(0) function addAlert(alert) { alertList.value.unshift(alert) totalCount.value } function clearAlerts() { alertList.value [] totalCount.value 0 } return { alertList, totalCount, addAlert, clearAlerts } })再新建/src/views/StatisticsView.vuetemplate div classstatistics-page h2数据统计/h2 el-row :gutter16 el-col :span8 el-card div classstat-number{{ alertStore.totalCount }}/div div classstat-label累计告警/div /el-card /el-col el-col :span8 el-card div classstat-number{{ handledCount }}/div div classstat-label已处理告警/div /el-card /el-col el-col :span8 el-card div classstat-number{{ unhandledCount }}/div div classstat-label未处理告警/div /el-card /el-col /el-row el-card classtip-card p提示当前页面使用 Pinia 管理告警状态当你从实测监控页触发新告警后这里的统计数据会同步更新。/p /el-card /div /template script setup import { computed } from vue import { useAlertStore } from ../stores/alert const alertStore useAlertStore() const handledCount computed(() { return alertStore.alertList.filter(item item.status 已处理).length }) const unhandledCount computed(() { return alertStore.alertList.length - handledCount.value }) /script style scoped .stat-number { font-size: 36px; font-weight: 700; text-align: center; color: #409eff; } .stat-label { text-align: center; margin-top: 8px; color: #909399; } .tip-card { margin-top: 20px; color: #909399; } /style然后更新路由文件/src/router/index.js把三个页面挂上import { createRouter, createWebHistory } from vue-router import MonitorView from ../views/MonitorView.vue import AlertCenterView from ../views/AlertCenterView.vue import StatisticsView from ../views/StatisticsView.vue const router createRouter({ history: createWebHistory(), routes: [ { path: /, name: monitor, component: MonitorView }, { path: /alerts, name: alerts, component: AlertCenterView }, { path: /statistics, name: statistics, component: StatisticsView } ] }) export default router最后修改/src/App.vue加一个顶部导航栏template div classapp-container header classapp-header h1AI 智能监控系统/h1 nav router-link to/实时监控/router-link router-link to/alerts告警中心/router-link router-link to/statistics数据统计/router-link /nav /header main classapp-main router-view / /main /div /template style * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, sans-serif; background: #f5f7fa; } .app-header { background: #1f2d3d; color: #fff; padding: 16px 32px; display: flex; justify-content: space-between; align-items: center; } .app-header h1 { font-size: 20px; } nav a { color: #fff; text-decoration: none; margin-left: 20px; opacity: 0.85; } nav a.router-link-active, nav a:hover { opacity: 1; border-bottom: 2px solid #409eff; padding-bottom: 4px; } .app-main { max-width: 1200px; margin: 0 auto; padding: 24px; } /style到这里前端界面已经具备基本功能。注意告警中心页面目前用的是本地假数据实时监控页会通过 HTTP 请求后端获取最新告警。为了让整体数据联动更顺畅后面可以在告警中心模块里也用 Pinia 中的alertList替代假数据真正完成全局状态联动。5. 简易 AI 检测后端Python OpenCV5.1 后端服务设计前端已经搭好接下来需要一个后端服务提供两样东西视频流地址持续输出带检测框的画面。最新告警接口返回当前检测到的事件类型。我们使用 Python 的 Flask 框架 OpenCV 来完成。OpenCV 是一个开源计算机视觉库用它读取摄像头素材、做基础的图像处理然后使用一个预训练的目标检测模型进行推理。这里需要说明标题和关键词里出现了 YOLOv5 和 PyTorch但为了让你 1 小时内能跑通本文先用 OpenCV 的 DNN 模块加载一个轻量级的 MobileNet SSD 模型它不需要安装 PyTorchCPU 也能顺畅运行。训练自己的 YOLOv5 模型是后话不影响你理解整个监控系统的数据流。后端项目结构如下ai-monitor-backend/ ├── app.py ├── requirements.txt └── models/ └── mobilenet_iter_24000_scale_0.5_fp16.caffemodel5.2 安装依赖新建后端目录准备requirements.txtflask3.0.0 flask-cors4.0.0 opencv-python4.9.0.80 numpy1.26.2在终端中安装依赖pip install -r requirements.txt如果国内网络下载较慢可以换成清华镜像源pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple5.3 编写后端代码app.py的核心逻辑是打开一个本地视频文件或者摄像头画面。对每一帧图像做人形目标检测。将检测结果和画框后的帧保存为 MJPEG 流返回给前端。当检测到人时记录一条最新告警。为了代码简洁且能直接运行示例使用摄像头索引0。如果你没有摄像头也可以把视频文件路径传进去或者使用一个测试视频素材。# app.py import cv2 import numpy as np from flask import Flask, Response, jsonify from flask_cors import CORS app Flask(__name__) CORS(app) MODEL_PATH models/mobilenet_iter_24000_scale_0.5_fp16.caffemodel CONFIG_PATH models/mobilenet_ssd_deploy.prototxt net cv2.dnn.readNetFromCaffe(CONFIG_PATH, MODEL_PATH) CLASSES [background, aeroplane, bicycle, bird, boat, bottle, bus, car, cat, chair, cow, diningtable, dog, horse, motorbike, person, pottedplant, sheep, sofa, train, tvmonitor] latest_alert { id: 0, message: } def detect_person(frame): h, w frame.shape[:2] blob cv2.dnn.blobFromImage(cv2.resize(frame, (300, 300)), 0.007843, (300, 300), 127.5) net.setInput(blob) detections net.forward() person_count 0 for i in range(detections.shape[2]): confidence detections[0, 0, i, 2] if confidence 0.5: class_id int(detections[0, 0, i, 1]) if CLASSES[class_id] person: person_count 1 box detections[0, 0, i, 3:7] * np.array([w, h, w, h]) (x1, y1, x2, y2) box.astype(int) cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(frame, person, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2) return frame, person_count def generate_frames(): cap cv2.VideoCapture(0) global latest_alert while True: success, frame cap.read() if not success: break frame, person_count detect_person(frame) if person_count 0: latest_alert[id] 1 latest_alert[message] f检测到 {person_count} 人 ret, jpeg cv2.imencode(.jpg, frame) frame_bytes jpeg.tobytes() yield (b--frame\r\n bContent-Type: image/jpeg\r\n\r\n frame_bytes b\r\n) app.route(/api/video_feed) def video_feed(): return Response(generate_frames(), mimetypemultipart/x-mixed-replace; boundaryframe) app.route(/api/latest_alert) def latest_alert_api(): return jsonify(latest_alert) if __name__ __main__: app.run(host0.0.0.0, port5000, threadedTrue)这个后端的关键点在于generate_frames函数它会不断从摄像头读取画面调用detect_person检测人形并在画面上绘制绿色矩形框最后将每一帧编码为 JPEG 图片以 MJPEG 流的方式推送给前端。/api/latest_alert就是前端轮询的接口只要检测到人就会返回最新一条告警信息。如果你在内网环境无法下载 Caffe 模型文件也可以退而求其次先用 OpenCV 自带的 HOG 人形检测器做一个极简版本把核心关注点放在前端视频流和告警联动上。6. 前后端联调与运行验证6.1 启动后端服务进入后端目录执行python app.py看到如下输出说明后端启动成功* Running on all addresses (0.0.0.0) * Running on http://127.0.0.1:5000此时在浏览器直接访问http://localhost:5000/api/video_feed如果摄像头正常你应该能看到带绿色检测框的视频画面。6.2 启动前端项目回到前端项目目录执行npm run dev浏览器打开http://localhost:5173进入实时监控页面后由于 Vite 代理配置已经将/api转发到后端因此页面上的img可以正常加载视频流。当你走到摄像头前右侧会实时出现“检测到 1 人”的告警记录。6.3 预期效果实时监控页左侧显示带检测框的实时画面右侧每 3 秒刷新一次最新告警。告警中心页展示全部历史告警点击“标记处理”可以更新状态。数据统计页累计告警数会随着实时监控页产生的告警不断增加。整个联动链路是OpenCV 检测到人 - 更新最新告警变量 - 前端轮询接口 - 写入 Pinia - 监控页和统计页响应式更新。这一串流程理解透了你对 Vue3 的响应式、状态管理、网络请求就都有了实际体会。7. 常见问题与排查思路问题现象常见原因解决思路npm create vuelatest执行缓慢或卡住默认 npm 源访问慢执行npm config set registry https://registry.npmmirror.com切换镜像后重试启动时提示vite不是内部或外部命令依赖未安装完整执行npm install确保安装成功页面能打开但视频流不显示后端没启动或代理配置有误先单独访问http://localhost:5000/api/video_feed确认后端正常再检查vite.config.js代理摄像头打不开摄像头被占用或授权未通过关闭可能占用摄像头的程序浏览器中允许摄像头权限控制台提示 CORS 错误后端未配置 CORS后端已引入flask-cors确认CORS(app)已执行检测不到人模型文件路径错误或置信度阈值太高检查模型路径适当降低confidence 0.5的阈值pip install下载 OpenCV 较慢默认源在国外使用国内镜像源安装页面切换后告警数据丢失Pinia 数据是内存态刷新页面后会重置生产环境需要把告警持久化到数据库并考虑从后端接口重新拉取如果你遇到的是冷门报错建议优先查看终端里完整的报错堆栈把npm run dev和python app.py两端控制台的日志结合起来分析大部分问题都出在两个服务的端口不一致或代理路径不匹配上。8. 最佳实践与工程建议8.1 项目结构规范在真实项目中前端目录建议按业务模块划分而不是把所有页面堆在views下。常见的方式是src/ ├── api/ # 接口请求封装 ├── assets/ # 静态资源 ├── components/ # 公共组件 ├── composables/ # 组合式函数 ├── router/ # 路由配置 ├── stores/ # Pinia 状态 └── views/ # 页面组件接口请求统一放在api目录中用 Axios 实例统一配置baseURL和拦截器。不要把请求地址散落在各个页面组件里否则后期维护会非常痛苦。8.2 组合式函数抽取业务逻辑当页面逻辑变复杂后可以把检索、轮询、格式化等逻辑抽取到composables中。例如把告警轮询逻辑封装成一个useAlertPoller页面组件只需要调用它即可组件的代码会清晰很多。8.3 安全与权限本文示例中的后端接口没有做任何身份认证。在真实 AI 监控系统中视频流和告警信息属于敏感数据必须考虑最小权限原则。建议在生产环境中前端通过登录接口获取 Token。后端对/api/video_feed、/api/latest_alert等接口做 Token 校验。视频流地址不要长期暴露在明文 URL 中可考虑带签名时效的地址。涉及删除、更新告警的操作后端必须校验用户角色和资源所有权。所有操作都保留审计日志方便回溯。8.4 AI 能力升级方向如果你希望把监控系统接入真正的深度学习目标检测模型推荐从 YOLOv5 或 YOLOv8 入手。你需要准备带标注的图片数据集在 GPU 环境下训练模型然后把训练好的模型权重通过 ONNX 或 TensorRT 部署到后端。这样检测的准确率和召回率都会比 MobileNet SSD 好很多但环境和训练时间成本也会明显提升。可以把这个作为下一个阶段的学习目标。8.5 前端性能与维护建议视频监控页面会有大量帧数据持续刷新这是正常的网络开销。但在处理告警列表时要注意避免频繁操作 DOM 或创建过多响应式对象。一个可行的方法是把最新告警放到 Pinia 中统一管理页面上的表格只展示有限条数通过分页或滚动加载处理大量历史数据。同时轮询间隔要合理不建议小于 1 秒避免给后端造成不必要的压力。9. 总结与下一步到这里你已经完成了 Vue3 从环境搭建到实战项目的完整闭环。回顾一下你先掌握了 Node.js 环境的配置用官方脚手架创建了 Vue3 Vite 项目然后学习了ref、reactive、computed、watch、路由、Pinia 和组件通信这些核心语法接着实现了一个带实时视频流、告警中心和数据统计的 AI 监控系统前端最后用 Python Flask OpenCV 做了一个简易检测后端并成功完成前后端联调。这个过程虽然用到的技术不算深但跑通了“前端展示 - 网络请求 - 后端检测 - 数据回流 - 页面响应式更新”的完整链路。你可以接着做下面几件事把告警中心的假数据替换成从后端接口获取真实历史告警。给前端接入登录页面和路由守卫完善权限控制。用 ECharts 给数据统计页增加趋势图表。学习 WebSocket 方案替代轮询让告警推送更实时。尝试在本地安装 PyTorch 并部署一个真正训练过的检测模型替换掉当前的 MobileNet SSD。如果这篇文章对你有帮助可以收藏备用。实际动手过程中遇到任何报错欢迎在评论区把控制台日志贴出来我看到后会尽量帮你分析。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

全球债务已破百亿,高息时代吞噬未来 2026/9/3 19:05:31

全球债务已破百亿,高息时代吞噬未来

《低利率时代已死,现金流崛起》——真正稀缺的不是资本,而是承受高利率的能力3%的增长并不可怕,可怕的是近100%的公共债务,正遇上一场“钱变贵”的时代切换。全球经济仍在增长,却越来越不均匀。发达经济体债券收益率升…

阅读更多 →
国网2013版终端调试程序实战:从解压到现场调试全流程解析 2026/9/3 19:05:31

国网2013版终端调试程序实战:从解压到现场调试全流程解析

简介:国网2013版终端调试程序是一款面向电力行业终端运维与调试人员的专用工具,针对国网终端设备在参数配置、规约测试与数据读取等场景设计,可帮助现场人员快速完成终端联调与故障排查。压缩包共包含39个文件,整体大小约6.28MB&a…

阅读更多 →
高超声速飞行器再入轨迹规划Matlab仿真:从建模到约束处理全解析 2026/9/3 19:05:31

高超声速飞行器再入轨迹规划Matlab仿真:从建模到约束处理全解析

简介:面向飞行器轨迹规划研究与Matlab仿真应用,这份高超声速飞行器轨迹规划示例程序基于Gauss伪谱法和GPOPSII求解器,为科研人员、工程师及高校研究生提供从动力学建模到最优轨迹输出的完整参考,适用于科研与工程实践中的飞行路径…

阅读更多 →
A*算法从理论到真车落地:路径规划选型、实现与工程避坑全解析 2026/9/3 19:05:31

A*算法从理论到真车落地:路径规划选型、实现与工程避坑全解析

简介:这是一份面向MATLAB学习者与路径规划初学者的A 算法演示附件,对应博文中的完整可运行代码。压缩包共3个文件,其中两个.m文件分别实现两套A 路径搜索流程,包含图构建、启发式函数、开放列表管理、路径回溯与可视化等关键模块…

阅读更多 →
RAR压缩包密码忘了怎么办?Advanced RAR Password Recovery实操指南 2026/9/3 19:05:31

RAR压缩包密码忘了怎么办?Advanced RAR Password Recovery实操指南

简介:这是Advanced RAR Password Recovery 4.53的注册码分享包,面向因忘记密码而无法打开RAR压缩包的普通用户,以及需要批量恢复加密压缩包的办公人员。该工具支持暴力枚举、掩码匹配等多种方式找回密码,适用于个人资料恢复、旧档…

阅读更多 →
基于HAL库的OLED驱动开发:从I2C原理到实战排查 2026/9/3 19:02:30

基于HAL库的OLED驱动开发:从I2C原理到实战排查

简介:基于HAL库的STM32 OLED驱动开发资料,面向嵌入式初学者以及需要快速为项目接入信息显示模块的开发者。资料以STM32单片机为主控,围绕OLED驱动开发的完整流程展开:从GPIO推挽输出模式设置、I2C或SPI通信外设初始化和复用功能配…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞