uni-app 系列(五):常用 API 与原生能力
2026年8月5日 · 18 分钟
一、API 总览与调用风格
uni-app 的能力 API 都以 uni. 前缀调用,风格是 success/fail/complete 回调(大部分也支持 Promise)。按类别记:
| 类别 | 代表 API |
|---|---|
| 界面交互 | showToast / showModal / showLoading / showActionSheet |
| 路由 | navigateTo / switchTab /(见第二篇) |
| 网络 | request / uploadFile / downloadFile |
| 存储 | setStorageSync /(见第四篇) |
| 媒体 | chooseImage / previewImage / chooseVideo |
| 位置 | getLocation / chooseLocation / openLocation |
| 设备 | getSystemInfo / makePhoneCall / scanCode / vibrateShort |
| 登录支付 | login / getUserProfile / requestPayment |
二、登录:多端差异与统一账号
登录是跨端项目最容易踩坑的能力,因为各端拿到的凭证不一样。用条件编译分流,最后统一到后端换取自有 token(见第三篇条件编译):
export function platformLogin() {
// #ifdef MP-WEIXIN
// 微信小程序:uni.login 拿 code → 后端 code2session 换 openid/unionid
return uni.login({ provider: "weixin" }).then((r) =>
exchangeToken("wechat-mp", r.code)
);
// #endif
// #ifdef APP-PLUS
// App:拉起微信授权;iOS 上架若有三方登录,必须同时接 Apple 登录
return uni.login({ provider: "weixin" }).then((r) =>
exchangeToken("wechat-app", r.authResult)
);
// #endif
// #ifdef H5
// H5:走手机号验证码
return phoneLogin();
// #endif
}
关键设计:客户端只负责拿"临时凭证",后端用凭证换成统一的自有 JWT,并用微信 UnionID / 手机号把不同端的身份归并到同一账号。客户端全程只认自有 token,与登录方式解耦。
微信获取用户头像昵称,早期用
uni.getUserInfo,现规范是uni.getUserProfile(需用户点击触发),且微信已收紧,很多信息要走"头像昵称填写"能力。
三、支付
uni.requestPayment({
provider: "wxpay", // wxpay / alipay
orderInfo: paramsFromServer, // 后端下单返回的支付参数
success: () => uni.showToast({ title: "支付成功" }),
fail: (e) => console.log("支付取消/失败", e),
});
支付流程铁律:签名与下单必须在后端做。客户端只拿后端返回的支付参数调起收银台,绝不能把商户密钥放前端。
四、定位与地图
uni.getLocation({
type: "gcj02", // 国内用火星坐标系
success: (res) => console.log(res.latitude, res.longitude),
});
注意点:① 国内坐标系用 gcj02(直接用 wgs84 会偏移);② 微信小程序要在 manifest.json 声明 requiredPrivateInfos 和定位权限描述,否则调用失败;③ App 端要在 manifest 勾选 Geolocation 模块并配好各端 key。
五、文件上传
uni.chooseImage({
count: 9,
success: (res) => {
res.tempFilePaths.forEach((path) => {
uni.uploadFile({
url: "https://api.example.com/upload",
filePath: path,
name: "file",
header: { Authorization: "Bearer " + token },
success: (r) => console.log("上传成功", r.data),
});
});
},
});
生产实践:图片一般前端直传对象存储(OSS/COS)——后端下发临时签名,前端
uploadFile直传,减轻后端带宽压力。
六、App 端进阶:renderjs 与 nvue
这是 App 端性能与原生能力的两个进阶话题,面试常考。
逻辑层与视图层分离
小程序/App 架构是双线程:逻辑层(JS)与视图层分离,两者通过序列化通信。好处是安全与稳定,代价是频繁通信有性能开销(如高频动画、拖拽)。
renderjs:把逻辑放到视图层跑
renderjs 是运行在视图层的 JS,可直接操作 DOM、用浏览器/webview 的库(如 echarts、地图 SDK),避免逻辑层↔视图层频繁通信的卡顿。适合:图表、复杂动画、需要直接操作视图的第三方库。
<script module="echarts" lang="renderjs">
export default {
mounted() { /* 这里能直接操作 DOM、用 echarts */ }
}
</script>
nvue:App 端的原生渲染
nvue(native vue)在 App 端用原生渲染(基于 weex),性能接近原生,适合长列表、首屏、复杂滚动等对性能极致要求的页面。代价:CSS 支持更受限(走原生排版)、写法更接近 RN。
选择建议:普通页面用 .vue(webview 渲染,开发体验最好);性能瓶颈页面(长列表/复杂动画)用 nvue;需在视图层直接操作 DOM/用视图层库时用 renderjs。
uni-app x 则更进一步——全量用 UTS/UVUE 原生渲染取代 nvue 这套(见系列第七篇)。
七、本阶段必须掌握的知识点
-
uni.API 的分类与回调/Promise 风格。 - 多端登录差异:各端拿不同凭证 → 条件编译分流 → 后端换统一 token → UnionID/手机号归并账号。
- 支付/上传的安全铁律:签名下单在后端、密钥不上前端;图片直传对象存储。
- 定位用 gcj02 坐标系,权限需在 manifest 声明。
- 双线程架构,以及
renderjs(视图层跑 JS)与nvue(App 原生渲染)的定位与选择。
八、高频面试题
Q1:uni-app 里如何实现多平台登录并统一账号体系?
A:思路是"客户端拿凭证、后端换 token、按唯一标识归并"。客户端用条件编译分流各端登录:微信小程序 uni.login 拿 code、App 拉起微信授权、iOS 接 Apple、H5 走手机号;拿到的都是临时凭证,交给后端。后端用凭证换取各平台的 openid/unionid,并用微信 UnionID 或手机号把不同 provider 的身份归并到同一用户,再签发自有 JWT返回。客户端之后所有请求只带这个自有 token,与具体登录方式彻底解耦。
追问:为什么不直接用微信的 openid 当用户 ID?
A:因为 openid 是单个应用内的标识,同一个人在你的小程序、App、公众号里 openid 各不相同;且只认 openid 无法与手机号登录、Apple 登录的身份打通。正确做法是自建 users 表 + user_identities 表(一人多身份),用 UnionID(同一微信开放平台下跨应用一致)和手机号作为归并锚点,openid 只作为某个身份的字段。
Q2:renderjs 和 nvue 分别解决什么问题?什么时候用?
A:二者都为 App 端性能/能力服务。根源是小程序/App 的双线程架构(逻辑层与视图层分离,通信有开销)。renderjs 是跑在视图层的 JS,可直接操作 DOM、使用只能在视图层运行的库(echarts、地图 SDK),避免高频跨线程通信卡顿,适合图表和复杂动画;nvue 是 App 端的原生渲染方案(weex),性能接近原生,适合长列表、复杂滚动等性能敏感页面,但 CSS 支持受限、写法偏 RN。普通页面用 .vue 即可,出现性能瓶颈再针对性上 nvue 或 renderjs。
追问:既然 nvue 性能好,为什么不所有页面都用 nvue?
A:因为 nvue 用原生排版,CSS 支持大幅受限(很多 web 布局/属性不支持)、开发调试体验差、部分组件行为与 vue 页面不一致,开发成本高。它是"用开发便利换性能"的方案,只在真正需要极致性能的页面用,普通页面用 .vue(webview 渲染)体验和生态都更好。
Q3:uni-app 调用支付时,安全上要注意什么?
A:核心密钥与下单签名必须在后端。客户端只做两件事:向后端请求创建订单、拿到后端返回的支付参数后调 uni.requestPayment 调起收银台。商户密钥、签名逻辑绝不能放前端(会被反编译窃取)。支付结果也要以后端异步回调(支付平台通知服务器)为准,不能只信客户端 success 回调,防止伪造。
Q4:定位为什么要用 gcj02?直接用经纬度会怎样?
A:中国大陆的地图服务使用 **gcj02(火星坐标系)**做了加密偏移。如果用设备原始的 wgs84 坐标直接在国内地图上打点,会出现几百米的位置偏移。所以 uni.getLocation 在国内应指定 type: "gcj02",与地图坐标系一致才能对准。此外定位属敏感权限,微信小程序需在 manifest.json 配置 requiredPrivateInfos 与权限用途描述,否则调用会被拒绝。