
简介uniappvue2onenet 是一套面向 UniApp 与 Vue2 开发者的物联网应用实战资源重点演示移动端跨平台工程如何接入中国移动 OneNet 平台内容涵盖设备接入、界面搭建、数据通信、消息推送等关键环节也涉及 Vuex 状态管理、异步请求与错误处理、HTTPS 安全通信等常见问题适合学习跨端开发并希望把设备数据落到真实 App 的读者。压缩包共 103 个文件包括 Vue/JS 源码、JSON 配置、SVG/PNG 图标素材、HTML/CSS/SCSS 样式页面以及 4 个可直接安装体验的 APK整体约 48.34MB目录结构清晰便于对照源码与打包产物快速排查问题。资源还附带与真机运行、证书配置相关的配置文件能帮助理解 uni-app 在不同终端上的适配与发布要点避免在多端打包时踩坑。已有 452 人学习浏览你可以借助这套资源快速启动自己的 uni-appOneNet 项目或作为智能家居、远程监控类课程设计的改造蓝本。 手头正好有一套刚上线的“uniapp vue2 OneNET”物联网项目趁热把整个踩坑过程梳理一遍。这套组合不算新潮但胜在稳定、资料多、够用非常合适做设备数据采集、远程控制和可视化大屏这类场景。如果你正打算做类似的东西或者刚接触IoT平台开发这篇内容应该能帮你省掉不少弯路。1. 内容整体设计与思路拆解1.1 为什么还是选uniapp vue2而不是vue3先说结论如果你不是从零开始、时间充裕、团队没有vue3经验vue2版本在生态兼容性上依然是最稳的选择。uniapp虽说官方主推vue3但我实际编译下来vue3版本在微信小程序和App端的三端统一上偶尔会遇到插件不兼容、某些原生SDK适配不到位的问题。尤其是涉及到MQTT长连接、webview交互、地图SDK这类偏底层的功能vue2版本跑起来反而更顺。另外一点很实际很多公司存量代码就是vue2招聘来的开发也大多是vue2熟练工。如果你想快速把设备数据接到手机端做演示或试用vue2 uniapp是最快出活的一条路。1.2 OneNET在整套架构里的角色OneNET是中国移动旗下的物联网开放平台支持多种协议接入其中我们最常用的是MQTT和HTTP。它本质上是帮你把“设备接入、数据存储、指令下发”这些活都干了你不需要自己搭服务器来维护设备连接也不用担心设备量大了消息通道扛不住。说人话设备端用ESP8266或者4G模组把数据推到OneNET手机端通过MQTT订阅同一个主题拿到数据反向也可以下发指令控制设备。整个数据链路不需要你自己开发中间件OneNET相当于一个中转站加数据库这对个人开发者和小团队来说极其友好。2. 核心细节解析与实操要点2.1 设备接入OneNET前要想清楚的几个问题OneNET平台上有两种接入方式一个是老版“多协议接入”一个是新版“物联网开放平台”。这两个别搞混。老版多协议接入适合用MQTT自定义Topic控制灵活但设备影子、数据流展示这些功能相对简陋新版物联网平台更像一个完整的IoT业务中台有设备管理、规则引擎、数据可视化但接入流程更重。我这次用的是新版物联网开放平台因为它对MQTT的支持更完善而且数据流模板可以直接对接后续的图表展示省事很多。设备接入前你需要准备产品IDProductID设备名称DeviceName设备密钥DeviceSecret这三样是设备的“身份证”MQTT连接时都要用上。OneNET的鉴权方式和阿里云IoT不一样它用的是一机一密 token动态生成不是简单的用户名密码直连。token生成算法在官方文档里有简单说就是version2018-10-31resproducts/{pid}/devices/{deviceName}et过期时间methodmd5sign签名字符串这个签名规则必须搞清楚不然设备一直连不上。2.2 MQTT协议在uniapp端的适配手机端要连OneNET首先要选择一个能在uniapp里用的MQTT库。我实测下来最稳的是mqtt.js的4.x版本配合vue2项目直接用npm install mqtt --save装进去然后在main.js里全局挂载。连接参数的关键点连接地址wxs://mqtt.heclouds.com/mqtt注意是wxs不是wsOneNET支持WebSocket方式接入MQTT前端必须走这个协议端口443走WebSocket默认端口clientId产品ID_设备名称中间是下划线username产品IDpassword动态token这里有个坑uniapp的App端默认网络请求是走plus.net的但它内部对WebSocket的支持在部分安卓机型上不够稳定容易出现断线重连不上的问题。后来我改成在onShow周期里主动断开重连再把心跳间隔调到30秒才算稳定下来。3. 实操过程与核心环节实现3.1 OneNET平台侧配置流程先登录OneNET平台创建一个产品选择“MQTT”协议数据加密方式选“TLS加密可选”然后添加一个设备拿到设备三元组。接着在产品下配置数据流模板比如我把温度、湿度、经纬度、电量这些字段都定义好设备上传的数据就会自动落到对应的数据流里。OneNET的规则引擎还可以做数据清洗和告警触发比如温度超过阈值就推送消息到手机端我在演示版里配置了一条30度告警规则实测触发延迟大约在1秒内效果不错。3.2 uniapp端MQTT连接核心代码直接上封装好的代码这是我反复改过之后的最终版本已经测试过安卓App和微信小程序两个端都能跑通import mqtt from mqtt export function connectOneNET(options) { const { productId, deviceName, deviceSecret } options const clientId ${productId}_${deviceName} const username productId const password generateToken(productId, deviceName, deviceSecret) const client mqtt.connect(wxs://mqtt.heclouds.com/mqtt, { clientId, username, password, port: 443, reconnectPeriod: 5000, connectTimeout: 10000 }) client.on(connect, () { console.log(OneNET MQTT连接成功) client.subscribe($sys/${productId}/${deviceName}/thing/property/post/reply, { qos: 1 }) client.subscribe($sys/${productId}/${deviceName}/thing/service/property/set, { qos: 1 }) }) client.on(message, (topic, payload) { console.log(收到消息:, topic, payload.toString()) }) client.on(reconnect, () { console.log(正在重连...) }) client.on(error, (err) { console.error(MQTT错误:, err) }) return client }generateToken这个函数按官方签名算法实现即可核心是MD5加密。建议把过期时间设为当前时间往后加24小时避免频繁重新生成。3.3 数据上报与实时刷新设备端上报数据到OneNET后平台会按产品定义的数据流存储。手机端订阅了thing/property/post的响应主题就能收到设备上报之后平台的确认消息。如果是设备主动上报、手机被动接收这就是典型的订阅/发布模式。不过你还要处理好首次进入页面时拉取设备最新数据这个动作。因为MQTT只推送“此刻之后”的新消息历史数据它不负责。我的做法是页面加载时调一次OneNET的HTTP API获取设备最新数据点然后再建立MQTT连接订阅增量数据。两个配合起来页面体验就是“进来有数据之后实时更新”。HTTP获取最新数据点的接口长这样GET https://iot-api.heclouds.com/thing-model/product/{productId}/device/{deviceName}/property/latest请求头里带上Authorization: {token}这个token同样的算法生成只是res参数改成products/{productId}expireTime和签名规则一致。3.4 指令下发与设备控制从手机端控制设备走的是OneNET的“属性设置”或“服务调用”。我在uniapp里做了几个按钮点击事件里调用平台API下发指令uni.request({ url: https://iot-api.heclouds.com/thing-model/product/${productId}/device/${deviceName}/thing/service/invoke, method: POST, header: { Authorization: token, Content-Type: application/json }, data: { identifier: switch, input: { value: 1 } }, success: (res) { // 指令下发成功后设备端会收到并返回执行结果 } })设备端收到指令后执行动作再把最新状态上报回来这样手机端就能看到完整的控制链路。注意指令下发走的是HTTP API不是MQTT这一点很多初学者会搞混。3.5 地图与定位组件嵌入如果你的设备带GPS那么手机端展示设备位置就涉及地图组件。uniapp内置了map组件但需要处理一个坐标系问题。设备端的GPS芯片输出的通常是WGS84坐标系而国内地图高德、腾讯用的是GCJ-02两者之间会有几十到几百米的偏差。这就解释了为什么有的项目明明坐标对地图上却偏到隔壁楼。处理办法在uniapp里封装一个坐标转换函数把WGS84转GCJ-02再传给map组件。网上有成熟的转换代码核心是一个偏移算法不需要引入第三方SDK。另外如果H5端要做定位uni.getLocation默认返回的是GCJ-02坐标App端则需要配置manifest里的定位权限声明否则安卓上直接拿不到定位结果。3.6 打包与上架需要注意的细节uniapp项目最终要变成App常见的做法是用HBuilderX云打包。云打包省事不需要本地配Android SDK但有一些细节不处理好会上架被拒或者运行崩溃。首先要设置manifest.json里的App模块权限MQTT和WebSocket是不需要额外模块的但定位、相机、推送这些必须按需勾选。勾多了会增加包体且可能触发隐私合规检测问题勾少了运行时会报module is not defined。其次上架安卓应用市场要求App必须适配64位架构。在HBuilderX云打包时选择ARM64和x86_64两个ABIARMv7按需选择。实测只打包ARM64的话部分老安卓机会跑不起来建议都勾上反正体积增加不大。上架时的隐私政策弹窗也要提前做好。uniapp官方提供了uni.getPrivacySetting和uni.requirePrivacyAuthorize接口需要在App启动时弹窗告知用户采集哪些数据。我遇到过一个上架被拒的真实案例就是因为“隐私政策未在首次启动时明确弹窗告知”后来加了启动弹窗引导才过审。4. 常见问题与排查技巧实录4.1 MQTT频繁断开重连也救不回来现象App进入后台一段时间后再切回MQTT已经断开了而且自动重连一直失败。原因App进入后台后WebSocket连接会被系统挂起或切断。重新回到前台时客户端检测到连接断开但重连时拿到的clientId已经被服务端残留连接占用导致握手失败。解决在onShow生命周期里主动调用client.end(true)强制断开旧连接然后重新创建连接。同时把心跳周期设为30秒在connect事件里间歇性发送ping请求保持连接活跃。4.2 微信小程序里MQTT连接报错WebSocket is not a constructor现象在H5端调试一切正常真机预览到微信小程序就报错。原因微信小程序的运行环境没有浏览器的原生WebSocket对象mqtt.js默认依赖WebSocket需要额外适配。解决在main.js里引入tencent/wx-ws或者直接使用uniapp自带的uni.connectSocket做一层适配。推荐后者因为它是uniapp官方API三端通用性最好。但要注意uni.connectSocket做的适配不能完全兼容mqtt.js的所有参数最简单的做法还是用mqtt.js官方提供的wx小程序适配模块。4.3 renderjs处理视频播放黑屏现象在App端用renderjs方式播放本机录制的MP4视频iOS正常安卓部分机型黑屏。原因renderjs运行在独立的JS上下文中媒体播放器组件层级问题导致渲染层和逻辑层不同步部分安卓机的H5 video组件无法正常解码本地视频文件。解决不用renderjs承载视频播放改用video原生组件加上controls属性。如果必须用renderjs做复杂交互建议把视频解码后转成HTTP流或base64格式再喂给组件但这会增加内存开销数据量大时慎用。4.4 打包后App内背景图不显示现象H5和微信小程序都正常App打包后背景图变成空白。原因uniapp的App端对CSS中引用本地图片路径的解析和H5端不一致尤其是background-image引用/static/路径下的图片在某些版本里会找不到资源。解决把背景图改为基础组件image铺满或者使用网络图片URL。另外图片名不要用中文字符打包后路径会乱掉这是老坑了。5. 经验心得与后续扩展建议我实际用下来这个组合最适合的项目规模是几百台以内设备、实时性要求不高秒级即可、团队前端为主没有专业IoT后端开发的场景。如果设备量到了几千上万台建议把消息链路改成更底层的EMQX自建但那就是另一个故事了。最后分享一个我在权限处理上的坑OneNET的token有效期设太长有安全风险设太短又要频繁重新生成。我最后做了一个通用方案在App本地存储token和过期时间每次请求前判断剩余有效期小于1小时就自动重新生成。这样既保证安全用户体验也不会受影响。这套机制跑了一个多月稳定性和安全性都经得住考验。本文还有配套的精品资源点击获取