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 中非常实用的页面通信模式,特别适合用于跨页面状态同步。

posted @ 2026-01-23 11:46  启航黑珍珠号  阅读(23)  评论(0)    收藏  举报