uni.getLocation 在不同平台行为差异大:iOS微信拒绝定位,Android App需手动开启后台权限,H5需HTTPS+用户主动触发;uni.chooseLocation仅支持微信小程序和App真机调试,H5不支持;uni.openLocation参数须全为字符串且经纬度合法;自定义地图应缓存mapContext并用onLocationChange替代轮询。
uni-app 的 uni.getLocation 代码本身并未写错,各端表现有别来自严格的平台限制:定位会被 iOS 微信浏览器直接拒绝,后台定位权限在 Android App 中默认关闭;浏览器则决定 H5 端的能力,Chrome 89+ 只有在 HTTPS 环境且用户主动触发时才会响应,例如点击按钮,否则失败过程没有提示。
常见错误现象:getLocation:fail systemError: Location module is not available 或返回 { errMsg: "getLocation:ok", latitude: 0, longitude: 0 } —— 这是降级兜底值,不是真实位置。
manifest.json 中手动勾选「定位」权限,iOS 还需填写 NSLocationWhenInUseUsageDescription 描述onLoad 中直接调用,应改成点击按钮后触发,以免被浏览器拦截app.json 的 permission 字段中声明 scope.userLocation
uni.chooseLocation 宿主环境提供的地图能力是它的依赖,因此它不属于纯 JS 方法:原生地图 SDK 是 App 端的必要支持,腾讯地图由微信小程序自动采用;至于 H5 端,则因完全不受支持而在调用时直接报错 chooseLocation:fail api not exists。
它的适用范围很清楚:仅适合微信小程序,或打包为 App 后进行真机调试,H5 页面不要使用这个 API。
manifest.json → 模块配置 → Maps 已经启用(高德 or 百度)project.config.json 内配置 libVersion 部分机型只有达到 ≥ 2.10.4 才能唤起地图address iOS App 上该字段存在空值可能,应把获取优先级给到 name 并利用经纬度自行进行逆地理编码uni.openLocation 它属于跳转动作,而不是渲染组件。本质上,它会拼接 URL 或唤起原生地图 App,因此参数略有偏差便可能出现白屏或报错 openLocation:fail invalid data。
必须全部采用字符串类型,是这些参数的关键要求;对于数字则要 toString();latitude 和 longitude 必须为合法小数,例如 39.9087,不可使用 39.90870000000001);到了 H5 端,能够支持的只有高德、百度、腾讯三家 URL 协议,同时 scheme 不可缺少。
name 和 address 并非必需,但微信小程序一定要传 name,不然地图不会显示标题try { uni.openLocation(...) } catch { window.location.href = 'https://uri.amap.com/marker?position=...' }
uni-app 官方 map 组件中的 mapContext 实例不能重复利用,每次调用 uni.createMapContext 都会创建新的上下文。如果在 onReady 或被频繁创建于滚动监听中,随之而来的将是缩放卡顿、定位点闪烁与内存泄漏。
低端 Android 机连续调用 5 次时,性能下降尤为明显 getCenterLocation 便可能掉帧;在 iOS 上多次 moveToLocation 则可能引发地图重绘并阻塞 UI。
mapContext 保存至 data 或 ref 中,并且只在 onReady 初始化一次uni.onLocationChange 来替代轮询 getLocation,从而减少上下文操作markers 借助数组单次 setData,可避开 diff 所产生的开销更难处理的是逆地理编码:uni-app 并未提供内置接口,需要自行请求高德/腾讯的 HTTP API,同时处理跨域、配额和密钥暴露风险。这个环节最容易被遗漏,最终造成上线后用户打开地图时只看到“未知位置”。