Files
Neo-ZQYY/_DEL/wechat-miniprogram/steering/app-service.md
2026-03-15 10:15:02 +08:00

256 lines
6.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 逻辑层App Service
> 官方文档https://developers.weixin.qq.com/miniprogram/dev/framework/app-service/
逻辑层使用 JavaScript 引擎运行,不在浏览器中,没有 `window``document` 等 Web API。
## App() — 注册小程序
```javascript
App({
onLaunch(options) {
// 小程序初始化时触发,全局只触发一次
// options.scene — 场景值
// options.query — 启动参数
// options.path — 启动页面路径
},
onShow(options) {
// 小程序启动或从后台进入前台时触发
},
onHide() {
// 小程序从前台进入后台时触发
},
onError(msg) {
// 小程序发生脚本错误或 API 调用失败时触发
console.error(msg)
},
onUnhandledRejection(res) {
// 未处理的 Promise 拒绝事件
console.warn(res.reason, res.promise)
},
onPageNotFound(res) {
// 页面不存在时触发
wx.redirectTo({ url: 'pages/...' })
},
onThemeChange({ theme }) {
// 系统主题变更dark / light
},
globalData: {
userInfo: null
}
})
```
获取 App 实例:
```javascript
const app = getApp()
console.log(app.globalData)
```
**注意**
- 不要在 `App()` 内调用 `getApp()`,使用 `this` 即可
- 不要在 `onLaunch` 时调用 `getCurrentPages()`,此时 page 还没有生成
## Page() — 注册页面
```javascript
Page({
data: {
text: 'Hello',
array: [{ msg: '1' }, { msg: '2' }]
},
// ===== 生命周期 =====
onLoad(options) {
// 页面加载时触发options 为页面路由参数
// 一个页面只会调用一次
},
onShow() {
// 页面显示/切入前台时触发
},
onReady() {
// 页面初次渲染完成时触发
// 一个页面只会调用一次,代表页面已可以和视图层交互
},
onHide() {
// 页面隐藏/切入后台时触发(如 navigateTo 或底部 tab 切换)
},
onUnload() {
// 页面卸载时触发(如 redirectTo 或 navigateBack
},
// ===== 页面事件处理 =====
onPullDownRefresh() {
// 下拉刷新(需在 json 中开启 enablePullDownRefresh
// 处理完后调用 wx.stopPullDownRefresh()
},
onReachBottom() {
// 上拉触底(可在 json 中设置 onReachBottomDistance
},
onShareAppMessage(res) {
// 用户点击右上角转发
// res.from: 'button' 或 'menu'
return {
title: '自定义转发标题',
path: '/pages/index/index',
imageUrl: '' // 自定义图片路径
}
},
onShareTimeline() {
// 分享到朋友圈(基础库 2.11.3+
return { title: '', query: '', imageUrl: '' }
},
onPageScroll(res) {
// 页面滚动时触发res.scrollTop 为垂直滚动距离(px)
// 注意:频繁触发,避免在此做复杂操作
},
onResize(res) {
// 页面尺寸变化时触发(如屏幕旋转)
},
onTabItemTap(item) {
// 当前是 tab 页时,点击 tab 时触发
// item.index / item.pagePath / item.text
},
// ===== 自定义方法 =====
viewTap() {
this.setData({
text: 'Set some data for updating view.'
})
}
})
```
### 页面生命周期顺序
```
onLoad → onShow → onReady → [onHide → onShow] → onUnload
```
### setData 详解
```javascript
// 基本用法
this.setData({
text: 'changed data'
})
// 修改数组某一项
this.setData({
'array[0].msg': 'changed'
})
// 修改对象某个属性
this.setData({
'object.key': 'value'
})
// 带回调
this.setData({ text: 'new' }, function() {
// setData 引起的界面更新渲染完毕后的回调
})
```
**setData 性能注意事项**
- 数据量不宜过大(单次 setData 不超过 1MB建议不超过 256KB
- 不要频繁调用(如 onPageScroll 中不要每次都 setData
- 只传需要更新的数据,不要整个 data 都传
- 后台页面不要 setData页面 onHide 后避免 setData
## 页面路由
框架以栈的形式维护当前所有页面,最多 10 层。
| 路由方式 | 触发时机 | 路由前页面 | 路由后页面 |
|----------|----------|-----------|-----------|
| 初始化 | 小程序打开第一个页面 | | onLoad, onShow |
| 打开新页面 | wx.navigateTo / `<navigator open-type="navigate">` | onHide | onLoad, onShow |
| 页面重定向 | wx.redirectTo / `<navigator open-type="redirect">` | onUnload | onLoad, onShow |
| 页面返回 | wx.navigateBack / 用户左上角返回 | onUnload | onShow |
| Tab 切换 | wx.switchTab / `<navigator open-type="switchTab">` / 用户切换 Tab | | 各种情况 |
| 重启动 | wx.reLaunch / `<navigator open-type="reLaunch">` | onUnload | onLoad, onShow |
```javascript
// 保留当前页面,跳转到新页面(页面栈 +1
wx.navigateTo({ url: '/pages/detail/detail?id=1' })
// 关闭当前页面,跳转到新页面(页面栈不变)
wx.redirectTo({ url: '/pages/detail/detail?id=1' })
// 关闭所有页面,打开某个页面
wx.reLaunch({ url: '/pages/index/index' })
// 跳转到 tabBar 页面,关闭其他所有非 tabBar 页面
wx.switchTab({ url: '/pages/index/index' })
// 返回上一页delta 为返回的页面数)
wx.navigateBack({ delta: 1 })
```
### 页面间通信EventChannel
```javascript
// 页面 A
wx.navigateTo({
url: '/pages/B/B',
events: {
// 监听来自 B 页面的事件
acceptDataFromOpenedPage(data) {
console.log(data)
}
},
success(res) {
// 向 B 页面发送数据
res.eventChannel.emit('acceptDataFromOpenerPage', { data: 'test' })
}
})
// 页面 B
Page({
onLoad() {
const eventChannel = this.getOpenerEventChannel()
// 向 A 页面发送数据
eventChannel.emit('acceptDataFromOpenedPage', { data: 'from B' })
// 监听来自 A 页面的数据
eventChannel.on('acceptDataFromOpenerPage', (data) => {
console.log(data)
})
}
})
```
## 模块化
```javascript
// common.js
function sayHello(name) {
console.log(`Hello ${name}!`)
}
module.exports.sayHello = sayHello
// 使用
const common = require('common.js')
common.sayHello('MINA')
```
**注意**
- 小程序不支持直接引入 `node_modules`,需使用 npm 构建或手动拷贝
- 每个文件有独立作用域,不同文件中可声明同名变量
- 通过 `getApp()` 获取全局数据
## getCurrentPages()
```javascript
const pages = getCurrentPages()
const currentPage = pages[pages.length - 1] // 当前页面
const prevPage = pages[pages.length - 2] // 上一个页面
// 可以通过 prevPage.setData() 修改上一页数据(返回时生效)
```
## 在线查询
如需更详细信息,可抓取:
- App 参考https://developers.weixin.qq.com/miniprogram/dev/reference/api/App.html
- Page 参考https://developers.weixin.qq.com/miniprogram/dev/reference/api/Page.html
- 路由https://developers.weixin.qq.com/miniprogram/dev/framework/app-service/route.html