uni-app 页面通信实践:使用全局事件总线同步页面状态
在 uni-app 中,不同页面之间是相互独立的实例,当某个页面发生状态变化时(例如连接状态变化),如果希望其他页面能够及时响应,就需要一种跨页面通信机制。
这里介绍一种常见且简单的方式:使用 uni 提供的全局事件总线 $emit / $on / $off 实现页面通信。
一、为什么需要页面通信
在实际业务中,经常会遇到这样的场景:
- A 页面负责某些底层状态的监听(如连接状态、系统事件等)
- B 页面负责展示和操作这些状态
- 当 A 页面状态发生变化时,需要主动通知 B 页面进行 UI 更新
由于页面之间无法直接相互调用方法,因此需要一个解耦的通信方式。
二、通信方式选择:全局事件总线
uni-app 提供了全局事件机制:
uni.$emit:发送事件uni.$on:监听事件uni.$off:移除监听
该机制适合用于:
- 跨页面通信
- 一对多广播
- 不需要强引用页面实例的场景
三、发送方:列表页发送事件
在列表页中,当状态发生变化时,通过 uni.$emit 向全局发送事件:
notifyDetailPage() {
uni.$emit("connectionStatusChange", {
connected: false,
});
}
这里:
"connectionStatusChange"是事件名- 事件携带的数据通过对象形式传递
- 发送方不关心接收方是否存在,实现了解耦
四、接收方:详情页监听事件
在详情页的 onLoad 生命周期中注册事件监听:
async onLoad(option) {
this.onConnectionChange = (data) => {
if (data.connected === false) {
this.device.connected = false;
this.showSetting = false;
}
};
uni.$on("connectionStatusChange", this.onConnectionChange);
}
关键点说明:
- 使用具名函数保存回调引用
- 避免使用匿名函数,方便后续移除监听
- 接收到事件后,只处理自己关心的数据
五、页面卸载时移除监听(非常重要)
当页面被销毁或返回时,需要主动移除事件监听:
onUnload() {
if (this.onConnectionChange) {
uni.$off("connectionStatusChange", this.onConnectionChange);
}
}
如果不移除:
- 页面重新进入时会重复注册监听
- 同一个事件会被多次触发
- 容易造成内存泄漏和逻辑异常
六、这种通信方式的特点
优点:
- 实现简单,学习成本低
- 页面之间完全解耦
- 适合状态通知、广播类场景
注意点:
- 事件名需要统一管理,避免冲突
- 事件监听必须在合适的生命周期中注册和销毁
- 不适合复杂的双向通信或状态管理(可考虑 Vuex / Pinia)
七、小结
通过全局事件总线:
- 页面 A 可以在合适的时机 主动广播状态变化
- 页面 B 只需 监听事件并更新自身状态
- 两个页面无需直接依赖彼此,降低耦合度
这是一种在 uni-app 中非常实用的页面通信模式,特别适合用于跨页面状态同步。

浙公网安备 33010602011771号