432 lines
9.5 KiB
Markdown
432 lines
9.5 KiB
Markdown
# 前端 API
|
||
|
||
> 官方文档:https://developers.weixin.qq.com/miniprogram/dev/api/
|
||
|
||
## API 调用约定
|
||
|
||
小程序 API 分三类:
|
||
- **事件监听 API**:以 `on` 开头,如 `wx.onSocketOpen`
|
||
- **同步 API**:以 `Sync` 结尾,如 `wx.setStorageSync`
|
||
- **异步 API**:大多数 API,支持回调和 Promise
|
||
|
||
```javascript
|
||
// 回调风格
|
||
wx.request({
|
||
url: 'https://example.com/api',
|
||
success(res) { console.log(res.data) },
|
||
fail(err) { console.error(err) },
|
||
complete() { /* 无论成功失败都执行 */ }
|
||
})
|
||
|
||
// Promise 风格(基础库 2.10.2+,除部分 API 外均支持)
|
||
const res = await wx.request({ url: 'https://example.com/api' })
|
||
// 注意:部分 API 不支持 Promise,如 wx.downloadFile、wx.connectSocket 等
|
||
```
|
||
|
||
## 路由
|
||
|
||
```javascript
|
||
// 保留当前页面,跳转(栈 +1,最多 10 层)
|
||
wx.navigateTo({
|
||
url: '/pages/detail/detail?id=1&name=test',
|
||
events: { /* EventChannel 监听 */ },
|
||
success(res) { res.eventChannel.emit('data', {}) }
|
||
})
|
||
|
||
// 关闭当前页面,跳转
|
||
wx.redirectTo({ url: '/pages/other/other' })
|
||
|
||
// 关闭所有页面,打开
|
||
wx.reLaunch({ url: '/pages/index/index' })
|
||
|
||
// 跳转到 tabBar 页面(关闭其他非 tabBar 页面)
|
||
wx.switchTab({ url: '/pages/index/index' })
|
||
// ⚠️ switchTab 不支持带参数
|
||
|
||
// 返回
|
||
wx.navigateBack({ delta: 1 })
|
||
```
|
||
|
||
## 网络
|
||
|
||
### wx.request — HTTP 请求
|
||
```javascript
|
||
wx.request({
|
||
url: 'https://example.com/api/data',
|
||
method: 'POST', // GET, POST, PUT, DELETE, OPTIONS, HEAD, TRACE, CONNECT
|
||
data: { key: 'value' },
|
||
header: {
|
||
'content-type': 'application/json',
|
||
'Authorization': 'Bearer token'
|
||
},
|
||
timeout: 60000, // 超时时间(ms)
|
||
dataType: 'json', // 返回数据自动 JSON.parse
|
||
responseType: 'text', // text 或 arraybuffer
|
||
enableHttp2: false,
|
||
enableQuic: false,
|
||
enableCache: false,
|
||
success(res) {
|
||
res.statusCode // HTTP 状态码
|
||
res.data // 响应数据
|
||
res.header // 响应头
|
||
},
|
||
fail(err) {
|
||
err.errMsg // 错误信息
|
||
}
|
||
})
|
||
```
|
||
|
||
**注意事项**:
|
||
- 需在小程序管理后台配置合法域名(request 合法域名)
|
||
- 默认超时 60s,可在 `app.json` 的 `networkTimeout.request` 配置
|
||
- 最大并发限制 10 个
|
||
- HTTPS 只支持 TLS 1.2+
|
||
- `data` 为 Object 时:GET 请求会序列化为 query string;POST 请求 header 为 `application/json` 时序列化为 JSON,为 `application/x-www-form-urlencoded` 时序列化为 query string
|
||
|
||
### wx.uploadFile — 上传文件
|
||
```javascript
|
||
wx.chooseImage({
|
||
success(res) {
|
||
wx.uploadFile({
|
||
url: 'https://example.com/upload',
|
||
filePath: res.tempFilePaths[0],
|
||
name: 'file',
|
||
formData: { user: 'test' },
|
||
success(uploadRes) {
|
||
console.log(uploadRes.data)
|
||
}
|
||
})
|
||
}
|
||
})
|
||
```
|
||
|
||
### wx.downloadFile — 下载文件
|
||
```javascript
|
||
wx.downloadFile({
|
||
url: 'https://example.com/file.pdf',
|
||
success(res) {
|
||
if (res.statusCode === 200) {
|
||
wx.openDocument({ filePath: res.tempFilePath })
|
||
}
|
||
}
|
||
})
|
||
```
|
||
|
||
### WebSocket
|
||
```javascript
|
||
const socketTask = wx.connectSocket({
|
||
url: 'wss://example.com/ws',
|
||
header: { 'Authorization': 'Bearer token' }
|
||
})
|
||
|
||
socketTask.onOpen(() => {
|
||
socketTask.send({ data: 'hello' })
|
||
})
|
||
socketTask.onMessage((res) => {
|
||
console.log(res.data)
|
||
})
|
||
socketTask.onClose(() => {})
|
||
socketTask.onError((err) => {})
|
||
socketTask.close()
|
||
```
|
||
|
||
## 数据缓存
|
||
|
||
```javascript
|
||
// 异步
|
||
wx.setStorage({ key: 'key', data: 'value' })
|
||
wx.getStorage({
|
||
key: 'key',
|
||
success(res) { console.log(res.data) }
|
||
})
|
||
wx.removeStorage({ key: 'key' })
|
||
wx.clearStorage()
|
||
wx.getStorageInfo({
|
||
success(res) {
|
||
res.keys // 所有 key
|
||
res.currentSize // 当前占用(KB)
|
||
res.limitSize // 限制大小(KB)
|
||
}
|
||
})
|
||
|
||
// 同步
|
||
wx.setStorageSync('key', 'value')
|
||
const value = wx.getStorageSync('key')
|
||
wx.removeStorageSync('key')
|
||
wx.clearStorageSync()
|
||
```
|
||
|
||
**注意**:
|
||
- 单个 key 上限 1MB
|
||
- 总上限 10MB
|
||
- 隔离策略:同一小程序不同用户数据隔离
|
||
|
||
## 界面
|
||
|
||
### 交互反馈
|
||
```javascript
|
||
// Toast
|
||
wx.showToast({ title: '成功', icon: 'success', duration: 2000 })
|
||
wx.showToast({ title: '加载中', icon: 'loading' })
|
||
wx.showToast({ title: '自定义图标', icon: 'none' }) // 无图标,可显示两行文字
|
||
wx.hideToast()
|
||
|
||
// Loading
|
||
wx.showLoading({ title: '加载中', mask: true })
|
||
wx.hideLoading()
|
||
|
||
// Modal
|
||
wx.showModal({
|
||
title: '提示',
|
||
content: '确定删除?',
|
||
confirmText: '确定',
|
||
cancelText: '取消',
|
||
success(res) {
|
||
if (res.confirm) { /* 确定 */ }
|
||
else if (res.cancel) { /* 取消 */ }
|
||
}
|
||
})
|
||
|
||
// ActionSheet
|
||
wx.showActionSheet({
|
||
itemList: ['选项A', '选项B', '选项C'],
|
||
success(res) {
|
||
console.log(res.tapIndex) // 0, 1, 2
|
||
}
|
||
})
|
||
```
|
||
|
||
### 导航栏
|
||
```javascript
|
||
wx.setNavigationBarTitle({ title: '新标题' })
|
||
wx.setNavigationBarColor({
|
||
frontColor: '#ffffff', // 仅支持 #ffffff 和 #000000
|
||
backgroundColor: '#ff0000',
|
||
animation: { duration: 400, timingFunc: 'easeIn' }
|
||
})
|
||
wx.showNavigationBarLoading()
|
||
wx.hideNavigationBarLoading()
|
||
```
|
||
|
||
### 下拉刷新
|
||
```javascript
|
||
wx.startPullDownRefresh() // 触发下拉刷新
|
||
wx.stopPullDownRefresh() // 停止下拉刷新
|
||
```
|
||
|
||
### 滚动
|
||
```javascript
|
||
wx.pageScrollTo({
|
||
scrollTop: 0,
|
||
duration: 300
|
||
})
|
||
```
|
||
|
||
### TabBar
|
||
```javascript
|
||
wx.showTabBar()
|
||
wx.hideTabBar()
|
||
wx.setTabBarBadge({ index: 0, text: '1' })
|
||
wx.removeTabBarBadge({ index: 0 })
|
||
wx.showTabBarRedDot({ index: 0 })
|
||
wx.hideTabBarRedDot({ index: 0 })
|
||
wx.setTabBarItem({
|
||
index: 0,
|
||
text: '新文字',
|
||
iconPath: '/images/new-icon.png',
|
||
selectedIconPath: '/images/new-icon-active.png'
|
||
})
|
||
wx.setTabBarStyle({
|
||
color: '#000',
|
||
selectedColor: '#ff0000',
|
||
backgroundColor: '#ffffff'
|
||
})
|
||
```
|
||
|
||
## 媒体
|
||
|
||
### 图片
|
||
```javascript
|
||
// 选择图片(从相册或拍照)
|
||
wx.chooseMedia({
|
||
count: 9,
|
||
mediaType: ['image'],
|
||
sourceType: ['album', 'camera'],
|
||
sizeType: ['original', 'compressed'],
|
||
success(res) {
|
||
res.tempFiles // [{ tempFilePath, size, ... }]
|
||
}
|
||
})
|
||
|
||
// 预览图片
|
||
wx.previewImage({
|
||
current: 'url', // 当前显示图片的链接
|
||
urls: ['url1', 'url2', 'url3']
|
||
})
|
||
|
||
// 获取图片信息
|
||
wx.getImageInfo({
|
||
src: 'path/or/url',
|
||
success(res) {
|
||
res.width
|
||
res.height
|
||
res.path
|
||
res.orientation
|
||
res.type
|
||
}
|
||
})
|
||
|
||
// 保存图片到相册
|
||
wx.saveImageToPhotosAlbum({
|
||
filePath: 'tempFilePath',
|
||
success() {}
|
||
})
|
||
```
|
||
|
||
## 位置
|
||
|
||
```javascript
|
||
// 获取位置(需要用户授权 scope.userLocation)
|
||
wx.getLocation({
|
||
type: 'gcj02', // wgs84 或 gcj02
|
||
success(res) {
|
||
res.latitude
|
||
res.longitude
|
||
res.speed
|
||
res.accuracy
|
||
}
|
||
})
|
||
|
||
// 打开地图选择位置
|
||
wx.chooseLocation({
|
||
success(res) {
|
||
res.name
|
||
res.address
|
||
res.latitude
|
||
res.longitude
|
||
}
|
||
})
|
||
|
||
// 打开内置地图查看位置
|
||
wx.openLocation({
|
||
latitude: 23.099994,
|
||
longitude: 113.324520,
|
||
name: '位置名',
|
||
address: '详细地址',
|
||
scale: 18
|
||
})
|
||
```
|
||
|
||
## 文件系统
|
||
|
||
```javascript
|
||
const fs = wx.getFileSystemManager()
|
||
|
||
// 读文件
|
||
fs.readFile({
|
||
filePath: `${wx.env.USER_DATA_PATH}/hello.txt`,
|
||
encoding: 'utf8',
|
||
success(res) { console.log(res.data) }
|
||
})
|
||
|
||
// 写文件
|
||
fs.writeFile({
|
||
filePath: `${wx.env.USER_DATA_PATH}/hello.txt`,
|
||
data: 'some text',
|
||
encoding: 'utf8',
|
||
success() {}
|
||
})
|
||
|
||
// 其他:appendFile, mkdir, rmdir, readdir, stat, unlink, rename, copyFile, access
|
||
```
|
||
|
||
## WXML 节点查询
|
||
|
||
```javascript
|
||
// SelectorQuery
|
||
const query = wx.createSelectorQuery()
|
||
query.select('#the-id').boundingClientRect((rect) => {
|
||
rect.top // 节点上边界坐标
|
||
rect.right
|
||
rect.bottom
|
||
rect.left
|
||
rect.width
|
||
rect.height
|
||
})
|
||
query.selectViewport().scrollOffset((res) => {
|
||
res.scrollTop
|
||
res.scrollLeft
|
||
})
|
||
query.exec()
|
||
|
||
// 在组件中使用
|
||
const query = this.createSelectorQuery()
|
||
query.select('#the-id').boundingClientRect().exec(callback)
|
||
|
||
// IntersectionObserver(监听元素与视口交叉)
|
||
const observer = wx.createIntersectionObserver(this, { thresholds: [0, 0.5, 1] })
|
||
observer.relativeToViewport({ bottom: 100 })
|
||
observer.observe('.target-class', (res) => {
|
||
res.intersectionRatio // 交叉比例
|
||
res.intersectionRect // 交叉区域
|
||
})
|
||
// 停止监听
|
||
observer.disconnect()
|
||
```
|
||
|
||
## 系统信息
|
||
|
||
```javascript
|
||
// 同步获取(推荐用新 API)
|
||
const windowInfo = wx.getWindowInfo()
|
||
// windowInfo.windowWidth / windowInfo.windowHeight / windowInfo.pixelRatio
|
||
// windowInfo.statusBarHeight / windowInfo.safeArea
|
||
|
||
const appBaseInfo = wx.getAppBaseInfo()
|
||
// appBaseInfo.SDKVersion / appBaseInfo.language / appBaseInfo.theme
|
||
|
||
const deviceInfo = wx.getDeviceInfo()
|
||
// deviceInfo.platform / deviceInfo.brand / deviceInfo.model / deviceInfo.system
|
||
|
||
// 旧 API(仍可用但不推荐)
|
||
const sysInfo = wx.getSystemInfoSync()
|
||
```
|
||
|
||
## 转发分享
|
||
|
||
```javascript
|
||
// 页面中定义 onShareAppMessage 即可开启转发
|
||
Page({
|
||
onShareAppMessage(res) {
|
||
if (res.from === 'button') {
|
||
// 来自页面内转发按钮
|
||
}
|
||
return {
|
||
title: '自定义转发标题',
|
||
path: '/pages/index/index?id=123',
|
||
imageUrl: '/images/share.png'
|
||
}
|
||
},
|
||
onShareTimeline() {
|
||
// 分享到朋友圈(基础库 2.11.3+)
|
||
return {
|
||
title: '朋友圈标题',
|
||
query: 'id=123',
|
||
imageUrl: '/images/share.png'
|
||
}
|
||
}
|
||
})
|
||
```
|
||
|
||
```xml
|
||
<!-- 页面内转发按钮 -->
|
||
<button open-type="share">转发</button>
|
||
```
|
||
|
||
## 在线查询
|
||
|
||
API 文档非常庞大,如需查看某个具体 API 的完整参数,可抓取:
|
||
- API 总览:https://developers.weixin.qq.com/miniprogram/dev/api/
|
||
- 具体 API:`https://developers.weixin.qq.com/miniprogram/dev/api/{分类}/{api名}.html`
|
||
例如:https://developers.weixin.qq.com/miniprogram/dev/api/network/request/wx.request.html
|