uni-app 无法直接实现微信小程序 AR 实景导航,因其运行容器不支持摄像头流、传感器及 WebGL;可行方案是 uni-app 仅作入口跳转至原生小程序 AR 页面,或在编译后目录手动混写原生代码。

uni-app 无法直接实现微信小程序 AR 实景导航
结论很明确:uni-app 本身不支持调用微信小程序的 VKSession 或 AR 能力,因为它的运行容器(WebView / X5 内核)无法访问摄像头流、设备姿态传感器和 WebGL 渲染上下文——而这三者是 AR 导航的底层前提。
你看到的所谓“uni-app + AR”项目,几乎全是以下两种情况之一:
- 用
uni-app做壳,实际 AR 页面是独立的原生小程序页面(通过uni.navigateTo跳转),uni-app只负责入口和数据透传; - 用
uni-app打包出小程序代码后,在生成的miniprogram/目录里手动混写原生小程序代码(如pages/tracking/index),再引入ar.js或 EasyAR SDK,完全脱离vue生命周期管理。
试图在 .vue 文件里直接 import ar.js 或调用 wx.createVKSession,99% 会报错 Cannot read property 'createVKSession' of undefined,因为该 API 不在 uni-app 的运行时环境中暴露。
微信小程序 AR 导航必须用原生方式接入 VKSession
微信官方的 AR 实景导航能力只对原生小程序开放,核心是 VKSession 对象。它提供帧图像获取、平面检测(plane.mode: 1)、坐标系对齐等能力,而这些在 uni-app 的 web-view 或默认渲染层中不可用。
如果你坚持走 AR 路线,真实可行的路径是:
- 在
uni-app中仅做跳转入口:用uni.navigateTo({ url: '/pages/ar-nav/index' })打开一个纯原生小程序页面; - 该页面不使用
uni-app编译逻辑,而是手写index.wxml+index.js,并在onLoad中调用wx.createVKSession; - AR 渲染层必须用
canvas+WebGL(或three.js)叠加箭头,不能依赖map组件或cover-view—— 后者无法与摄像头画面做像素级对齐; -
VKSession.start()必须在用户授权scope.camera后调用,且需在manifest.json中配置"permission": { "scope.camera": { "desc": "用于AR导航" } }。
漏掉任意一步,都会卡在黑屏、无回调、或 getVKFrame 返回 null。
替代方案:用高德地图 + 定向箭头模拟“轻量 AR”
如果目标只是“在实景画面中指示方向”,而非严格意义上的空间锚定 AR(比如让箭头贴合地面、被真实物体遮挡),可以绕过 VKSession,改用更稳定的方式:
- 用
uni.chooseImage({ sourceType: ['camera'] })或camera组件获取实时画面(注意 iOS 需mode="scanCode"才能持续预览); - 同时用
uni.getLocation获取经纬度,再调用高德AMap.Geolocation获取精确 heading(设备朝向角); - 计算目标点相对于当前设备的方位角(
atan2公式),再结合屏幕宽高比,在 canvas 上动态绘制带旋转的箭头; - 关键点:
camera组件输出的是 4:3 或 16:9 视频流,而地图坐标系是球面,二者比例不一致,必须用设备screen.width/screen.height和camera实际输出分辨率做归一化校准,否则箭头偏移严重。
这种方式不依赖微信 AR 接口,iOS/Android 兼容性好,但缺点也很明显:无法处理倾斜、俯仰、遮挡,纯属“二维投影示意”。适合导览类 APP 中对精度要求不高的引导场景。
uni-app 地图组件能做的高级事:别碰 AR,先用好 markers/polyline
与其强上 AR,不如把 map 组件的原生能力挖深。微信小程序和 App 端的 map 组件都支持:markers(带自定义 iconPath 的点标记)、polyline(带颜色/宽度/虚实线的路线)、circles(半径可随缩放变化的圆形覆盖物)。
几个容易被忽略但实用的点:
-
markers的callout属性可配置是否显示气泡、背景色、文字大小,微信端支持display: 'BYCLICK'控制点击才弹出; -
polyline的arrowLine(微信独有)可自动绘制带箭头的折线,省去自己算角度画三角形; - App 端可通过
plus.mapsAPI 添加热力图(HeatmapOverlay)或矢量多边形(PolygonOverlay),但微信小程序不支持; - 所有覆盖物坐标必须是 WGS84 坐标系,高德返回的是 GCJ02,需用
AMap.Convertor.translate转换,否则偏移 300–500 米。
真正难的不是加图标,而是让 markers 动态跟随 GPS 移动时平滑过渡——微信小程序 map 组件不支持 animation,得靠 setCenterOffset + 定时 update 模拟,否则会出现“瞬移”感。











