8.1 原生 API 体系
uni-app 封装了数百个设备原生 API,统一以 uni. 前缀调用。这些 API 在各平台有不同的底层实现,但开发者写一套代码即可适配:
| 能力类别 | 主要 API |
|---|---|
| 界面交互 | showToast、showModal、showLoading、showActionSheet |
| 导航与路由 | navigateTo、setNavigationBarTitle、setTabBarBadge |
| 媒体 | chooseImage、chooseVideo、previewImage、getImageInfo |
| 文件 | uploadFile、downloadFile、saveFile、openDocument |
| 位置 | getLocation、openLocation、chooseLocation |
| 设备信息 | getSystemInfo、getWindowInfo、getNetworkType |
| 传感器 | startAccelerometer、startCompass、onGyroscopeChange |
| 支付 | requestPayment(微信支付、支付宝支付) |
| 分享 | share(App 端)、onShareAppMessage(小程序端) |
| 蓝牙/NFC | openBluetoothAdapter、startBluetoothDevicesDiscovery |
8.2 地理位置
// 获取当前位置(需要权限)
async function getCurrentLocation() {
try {
// App 端需先检查并申请权限
// #ifdef APP
const authorized = await requestLocationPermission()
if (!authorized) {
uni.showToast({ title: '需要位置权限', icon: 'none' })
return
}
// #endif
const location = await uni.getLocation({
type: 'gcj02', // GCJ-02 坐标(国内地图标准)
altitude: true, // 高度信息(App 端有效)
isHighAccuracy: true // 高精度(GPS,耗电更多)
})
console.log('经度:', location.longitude)
console.log('纬度:', location.latitude)
console.log('精度(米):', location.accuracy)
return location
} catch (err) {
console.error('获取位置失败:', err)
}
}
// 在地图中打开位置
uni.openLocation({
latitude: 39.9042,
longitude: 116.4074,
name: '天安门广场',
address: '北京市东城区'
})
// 让用户在地图上选择位置
const chosen = await uni.chooseLocation({})
console.log('用户选择的地点:', chosen.name, chosen.latitude, chosen.longitude)
坐标系说明
中国大陆使用 GCJ-02(火星坐标系),GPS 和国际标准使用 WGS-84。高德地图、腾讯地图使用 GCJ-02;百度地图使用 BD-09。uni.getLocation 的 type 参数决定返回哪种坐标系,选错坐标系会导致位置偏移数百米。
8.3 相机与图片
// 选择/拍摄图片
async function selectImage() {
const res = await uni.chooseImage({
count: 9, // 最多选 9 张
sizeType: ['original', 'compressed'], // 原图或压缩图
sourceType: ['album', 'camera'] // 相册或相机
})
// 预览图片
await uni.previewImage({
urls: res.tempFilePaths,
current: res.tempFilePaths[0] // 从第一张开始预览
})
}
// 压缩图片
async function compressImage(filePath: string) {
const res = await uni.compressImage({
src: filePath,
quality: 80 // 压缩质量 0-100
})
return res.tempFilePath
}
// 拍视频
const video = await uni.chooseVideo({
sourceType: ['album', 'camera'],
maxDuration: 60, // 最长 60 秒
camera: 'back' // 后置摄像头
})
8.4 权限申请最佳实践
App 端(Android/iOS)的原生权限需要运行时申请,如果直接调用 API 而不先申请权限,会导致 API 失败或 App 崩溃。
权限申请封装
// utils/permission.ts
// #ifdef APP-ANDROID
import { requestPermissions } from '@dcloudio/uni-app'
// #endif
/**
* 申请定位权限(Android + iOS)
* 返回 true 表示已授权
*/
export async function requestLocationPermission(): Promise<boolean> {
// #ifdef APP-ANDROID
const result = await uni.authorize({
scope: 'scope.userLocation'
}).catch(() => null)
if (!result) {
// 用户拒绝,引导去设置页开启
const { confirm } = await uni.showModal({
title: '需要位置权限',
content: '请在设置中允许访问您的位置,以获得更好的服务体验。',
confirmText: '去设置'
})
if (confirm) {
uni.openAppAuthorizeSetting()
}
return false
}
return true
// #endif
// #ifdef APP-IOS
// iOS 通过 Info.plist 中的描述文字申请,首次调用 API 时自动弹出系统弹窗
return true
// #endif
// #ifndef APP
return true // H5 和小程序由浏览器/小程序框架处理
// #endif
}
8.5 消息推送(uni-push 2.0)
uni-push 2.0 是 DCloud 推出的统一推送服务,底层集成了各厂商通道(FCM、华为、小米、OPPO、vivo、荣耀)和个推平台,实现系统级推送(App 关闭后仍能收到通知)。
客户端集成
// App.vue — 初始化推送
export default {
onLaunch() {
// #ifdef APP
initPush()
// #endif
}
}
function initPush() {
// 获取推送 token(cid),用于服务端向设备推送
uni.getPushClientId({
success(res) {
const cid = res.cid
console.log('推送 ClientID:', cid)
// 将 cid 发送到服务端,绑定用户
http.post('/api/push/register', { cid })
}
})
// 监听推送消息(App 处于前台时)
uni.onPushMessage((res) => {
const { data } = res
console.log('收到推送:', data)
if (data.type === 'order') {
// 订单状态推送,跳转到订单页
uni.navigateTo({ url: `/pages/order/detail?id=${data.orderId}` })
}
})
}
服务端发送推送(云函数)
// cloudfunctions/sendPush/index.js
const uniPush = uniCloud.getPushManager({ dcloudAppid: '__UNI__XXXXXXX' })
exports.main = async (event) => {
const { cid, title, content, data } = event
await uniPush.sendMessage({
push_clientid: cid, // 目标设备 ClientID
title, // 通知栏标题
content, // 通知栏内容
payload: data, // 自定义数据(JSON)
badge: 1, // iOS App 图标角标
sound: 'default' // 通知声音
})
return { code: 0 }
}
8.6 uni 插件市场
uni 插件市场(ext.dcloud.net.cn)是 uni-app 的官方插件生态,拥有数万个插件,覆盖 UI 组件、业务功能、设备能力等。
安装插件的方式
- HBuilderX 一键导入:在插件市场页面点击"使用 HBuilderX 导入插件",自动安装到
uni_modules/目录 - npm 安装:部分插件支持 npm 安装(如 uni-ui)
- 手动复制:将插件文件复制到项目目录
最常用的插件
npm install @dcloudio/uni-ui8.7 分享功能
// 微信小程序:配置页面分享
import { onShareAppMessage, onShareTimeline } from '@dcloudio/uni-app'
// 分享给朋友
onShareAppMessage(() => ({
title: '这个商品超好用!',
path: `/pages/detail/detail?id=${productId.value}`,
imageUrl: 'https://example.com/share-cover.jpg'
}))
// 分享到朋友圈(需要在 pages.json 中配置 enableShareTimeline)
onShareTimeline(() => ({
title: '发现好物,推荐给你!',
query: `id=${productId.value}`
}))
// App 端:系统原生分享
// #ifdef APP
uni.share({
provider: 'weixin', // 分享平台:weixin/qq/sinaweibo
scene: 'WXSceneSession', // WXSceneSession(发给朋友)/ WXSenceTimeline(朋友圈)
type: 0, // 0=网页链接 1=纯文字 2=图片 3=视频
href: 'https://example.com/product/42',
title: '这个商品超好用!',
summary: '限时特惠,点击查看详情',
imageUrl: 'https://example.com/cover.jpg'
})
// #endif
8.8 振动与音频
// 震动(提供轻微的触觉反馈)
uni.vibrateShort({ type: 'light' }) // light/medium/heavy(iOS 支持)
uni.vibrateLong() // 长震动(400ms)
// 背景音乐
const bgm = uni.getBackgroundAudioManager()
bgm.title = '轻音乐'
bgm.src = 'https://example.com/music.mp3'
bgm.play() // App 后台也能继续播放
// 音效(短音频)
const audio = uni.createInnerAudioContext()
audio.src = '/static/sounds/click.mp3'
audio.play()
8.9 小结
- uni-app 封装了数百个原生 API,统一以
uni.前缀调用,大部分支持 Promise - 地理位置注意坐标系(国内用 GCJ-02),权限申请需在 API 调用前完成
- 相机/图片选择后需要压缩再上传,减少流量消耗
- uni-push 2.0 集成了各厂商推送通道,实现系统级离线推送
- 插件市场提供丰富的现成方案,善用插件可以大幅减少开发工作量
- 权限被拒绝时,引导用户去系统设置页手动开启,而非直接报错