← 全部文章
uni-appAPI登录支付原生能力面试

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:renderjsnvue 分别解决什么问题?什么时候用?

A:二者都为 App 端性能/能力服务。根源是小程序/App 的双线程架构(逻辑层与视图层分离,通信有开销)。renderjs跑在视图层的 JS,可直接操作 DOM、使用只能在视图层运行的库(echarts、地图 SDK),避免高频跨线程通信卡顿,适合图表和复杂动画;nvue 是 App 端的原生渲染方案(weex),性能接近原生,适合长列表、复杂滚动等性能敏感页面,但 CSS 支持受限、写法偏 RN。普通页面用 .vue 即可,出现性能瓶颈再针对性上 nvuerenderjs

追问:既然 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 与权限用途描述,否则调用会被拒绝。

相关水晶