📱 Taro 从零到一(九):小程序原生能力调用
系列导读:小程序不仅是网页,还能调用扫码、定位、相机、支付等原生能力。 Taro 将各平台原生 API 统一封装,让你一套代码调用所有平台能力。
🗂 1. Taro API 分类
| 分类 | 常用 API | 用途 |
|---|---|---|
| 🔐 登录授权 | Taro.login / Taro.getUserInfo | 获取用户身份 |
| 📍 位置 | Taro.getLocation / Taro.chooseLocation | 定位和选址 |
| 📸 媒体 | Taro.chooseImage / Taro.chooseMedia | 拍照和选图 |
| 📋 剪贴板 | Taro.setClipboardData / Taro.getClipboardData | 复制粘贴 |
| 📲 扫码 | Taro.scanCode | 扫描二维码/条码 |
| 📞 电话 | Taro.makePhoneCall | 拨打电话 |
| 📦 存储 | Taro.setStorage / Taro.getStorage | 本地缓存 |
| 📤 分享 | useShareAppMessage | 分享到聊天 |
| 💰 支付 | Taro.requestPayment | 发起支付 |
| 🔔 通知 | Taro.requestSubscribeMessage | 订阅消息 |
🔐 2. 登录与用户信息
import Taro from '@tarojs/taro'
// 微信登录流程
async function wechatLogin() {
try {
// 1. 获取 code
const { code } = await Taro.login()
console.log('登录 code:', code)
// 2. 发送 code 到后端换取 token
const res = await http.post('/api/auth/wechat', { code })
const { token, user } = res
// 3. 保存登录状态
useAuthStore.getState().setAuth(token, user)
Taro.showToast({ title: '登录成功', icon: 'success' })
} catch (error) {
Taro.showToast({ title: '登录失败', icon: 'none' })
}
}
// 获取用户头像和昵称(微信新规需要用户主动填写)
function UserProfileForm() {
const [avatar, setAvatar] = useState('')
const [nickname, setNickname] = useState('')
const handleChooseAvatar = (e) => {
setAvatar(e.detail.avatarUrl)
}
return (
<View>
<Button openType="chooseAvatar" onChooseAvatar={handleChooseAvatar}>
<Image src={avatar || '/assets/default-avatar.png'} className="avatar" />
</Button>
<Input
type="nickname"
placeholder="请输入昵称"
onBlur={(e) => setNickname(e.detail.value)}
/>
</View>
)
}
📸 3. 图片选择与上传
async function chooseAndUploadImage() {
try {
// 1. 选择图片
const res = await Taro.chooseImage({
count: 9, // 最多 9 张
sizeType: ['compressed'], // 压缩
sourceType: ['album', 'camera'], // 相册 + 拍照
})
const filePaths = res.tempFilePaths
// 2. 逐个上传
const uploadResults = await Promise.all(
filePaths.map(filePath =>
Taro.uploadFile({
url: 'https://api.example.com/upload',
filePath,
name: 'file',
header: {
Authorization: `Bearer ${useAuthStore.getState().token}`,
},
})
)
)
// 3. 解析上传结果
const imageUrls = uploadResults.map(r => {
const data = JSON.parse(r.data)
return data.url
})
console.log('上传成功:', imageUrls)
return imageUrls
} catch (error) {
if (error.errMsg?.includes('cancel')) return []
Taro.showToast({ title: '上传失败', icon: 'none' })
return []
}
}
📍 4. 定位与地图
async function getCurrentLocation() {
try {
// 获取授权
const setting = await Taro.getSetting()
if (!setting.authSetting['scope.userLocation']) {
await Taro.authorize({ scope: 'scope.userLocation' })
}
// 获取位置
const location = await Taro.getLocation({
type: 'gcj02', // 国测局坐标(中国推荐)
isHighAccuracy: true,
})
console.log(`经度: ${location.longitude}, 纬度: ${location.latitude}`)
return location
} catch (error) {
Taro.showModal({
title: '提示',
content: '需要获取位置权限,请在设置中开启',
confirmText: '去设置',
success: (res) => {
if (res.confirm) Taro.openSetting()
},
})
}
}
// 选择地址
async function chooseAddress() {
const res = await Taro.chooseLocation({})
console.log('选择的地址:', res.name, res.address)
console.log('坐标:', res.latitude, res.longitude)
}
📋 5. 存储与缓存
// 封装存储工具
class Storage {
// 同步存储
static set(key: string, value: any) {
Taro.setStorageSync(key, JSON.stringify(value))
}
static get<T>(key: string, defaultValue?: T): T | undefined {
try {
const raw = Taro.getStorageSync(key)
return raw ? JSON.parse(raw) : defaultValue
} catch {
return defaultValue
}
}
static remove(key: string) {
Taro.removeStorageSync(key)
}
static clear() {
Taro.clearStorageSync()
}
// 带过期时间的存储
static setWithExpiry(key: string, value: any, ttlMs: number) {
const item = {
value,
expiry: Date.now() + ttlMs,
}
Taro.setStorageSync(key, JSON.stringify(item))
}
static getWithExpiry<T>(key: string): T | null {
try {
const raw = Taro.getStorageSync(key)
if (!raw) return null
const item = JSON.parse(raw)
if (Date.now() > item.expiry) {
Taro.removeStorageSync(key)
return null
}
return item.value
} catch {
return null
}
}
}
// 使用
Storage.set('userInfo', { name: '张三', age: 25 })
const user = Storage.get<User>('userInfo')
// 缓存接口数据 5 分钟
Storage.setWithExpiry('products', productList, 5 * 60 * 1000)
const cached = Storage.getWithExpiry<Product[]>('products')
📤 6. 分享
import { useShareAppMessage, useShareTimeline } from '@tarojs/taro'
function ProductDetailPage() {
// 分享给好友
useShareAppMessage(() => ({
title: '发现一个好物,推荐给你!',
path: `/pages/detail/index?id=${productId}`,
imageUrl: product.image,
}))
// 分享到朋友圈(微信支持)
useShareTimeline(() => ({
title: product.name,
query: `id=${productId}`,
imageUrl: product.image,
}))
return (
<View>
<Button openType="share">分享给好友</Button>
</View>
)
}
✅ 本篇小结 Checklist
- 掌握微信登录流程
- 会实现图片选择和上传
- 掌握定位和选择地址
- 会封装本地存储工具
- 实现分享功能
下一篇预告:《实战项目:从零搭建一个完整小程序》
本文是「Taro 从零到一」系列第 9 篇,共 10 篇。