Skip to content

useEventChannel

封装获取 EventChannel 并提供类型安全的 on/emit/off 便捷方法,用于页面间通信,监听上一个页面通过 EventChannel 传递的数据。需要在页面的 setup 中使用,且页面由 navigateTo 打开。组件卸载时会自动清理通过 on 注册的所有监听器。

平台支持

全平台

createEventChannelActions

纯函数,为任意 EventChannel 实例提供类型安全的 on/emit/off 方法,不依赖 Vue 生命周期,适用于发送页面(上一个页面)等非 setup 场景。

泛型参数

参数约束默认值说明
Textends IEventChannelMapIEventChannelMap事件数据类型映射,定义事件名与数据类型的对应关系

参数

参数类型说明
eventChannelUniApp.EventChannel需要包装的 EventChannel 实例

返回值

IEventChannelActions<T> — 包含 on/emit/off 的类型安全对象

使用示例

typescript
import { createEventChannelActions } from "uni-toolkit";

// 定义事件数据类型映射
type IMyEventMap = {
  acceptDataFromOpenerPage: { id: number; name: string };
  sendDataToOpenerPage: { reply: string; timestamp: number };
};

uni.navigateTo({
  url: "/pages/detail/index",
  events: {
    acceptDataFromOpenedPage: (data) => {
      console.log("收到下级页面数据:", data);
    }
  },
  success(res) {
    // 使用 createEventChannelActions 包装,获得类型安全的 emit
    const channel = createEventChannelActions<IMyEventMap>(res.eventChannel);
    // emit 具有类型约束,事件名和数据类型都会被检查
    channel.emit("acceptDataFromOpenerPage", { id: 1, name: "测试" });
  }
});

泛型参数

参数约束默认值说明
Textends IEventChannelMapIEventChannelMap事件数据类型映射,定义事件名与数据类型的对应关系

返回值

IEventChannelActions<T> | undefined — 包含 on/emit/off 的类型安全对象,获取 EventChannel 失败时返回 undefined

IEventChannelActions 方法

方法签名说明
on<K extends keyof T>(event: K, callback: IEventChannelCallback<T[K]>) => void类型安全的事件监听
emit<K extends keyof T>(event: K, data: T[K]) => void类型安全的事件发送
off<K extends keyof T>(event: K, callback?: IEventChannelCallback<T[K]>) => void类型安全的事件移除

相关类型

  • IEventChannelMap — 事件数据类型映射接口,Record<string, unknown>
  • IEventChannelCallback<T> — 事件回调函数类型,(data: T) => void

使用示例

基础用法

typescript
import { useEventChannel } from "uni-toolkit";

export default {
  setup() {
    const channel = useEventChannel();

    channel?.on("acceptDataFromOpenerPage", (data) => {
      console.log("收到数据:", data);
    });

    return {};
  }
};

带类型约束的用法

typescript
import { useEventChannel } from "uni-toolkit";

// 定义事件数据类型映射
type IMyEventMap = {
  acceptDataFromOpenerPage: { id: number; name: string };
  someOtherEvent: { message: string };
};

export default {
  setup() {
    const channel = useEventChannel<IMyEventMap>();

    // on — 类型安全,data 自动推导为 { id: number; name: string }
    channel?.on("acceptDataFromOpenerPage", (data) => {
      console.log("收到数据:", data.id, data.name);
    });

    // emit — 类型安全,data 必须匹配对应事件的数据类型
    channel?.emit("someOtherEvent", { message: "hello" });

    // off — 类型安全移除监听
    const handler = (data: { id: number; name: string }) => { /* ... */ };
    channel?.off("acceptDataFromOpenerPage", handler);

    // 组件卸载时自动清理,无需手动 off
    return {};
  }
};

发送页面配合使用

typescript
// 发送页面(上一个页面)
import { createEventChannelActions } from "uni-toolkit";

// 定义事件数据类型映射(与接收页面共享同一类型)
type IMyEventMap = {
  acceptDataFromOpenerPage: { id: number; name: string };
  sendDataToOpenerPage: { reply: string; timestamp: number };
};

uni.navigateTo({
  url: "/pages/detail/index",
  events: {
    acceptDataFromOpenedPage: (data) => {
      console.log("收到下级页面数据:", data);
    }
  },
  success(res) {
    // 使用 createEventChannelActions 包装,获得类型安全的 emit
    const channel = createEventChannelActions<IMyEventMap>(res.eventChannel);
    // emit 具有类型约束,事件名和数据类型都会被检查
    channel.emit("acceptDataFromOpenerPage", { id: 1, name: "测试" });
  }
});

特性

  • 封装 getOpenerEventChannel 调用,简化 EventChannel 获取
  • 提供类型安全的 on/emit/off 便捷方法,替代原始 EventChannel 操作
  • 支持泛型事件映射,事件名和数据类型完全约束
  • 组件卸载时自动清理通过 on 注册的所有监听器,防止内存泄漏
  • 开发环境下,获取 EventChannel 失败时输出 console.warn 警告
  • createEventChannelActions 纯函数,为任意 EventChannel 提供类型安全的 on/emit/off,不依赖 Vue 生命周期

注意事项

  1. 必须在页面的 setup 函数中调用
  2. 当前页面必须由 uni.navigateTo 打开,否则无法获取 EventChannel
  3. 开发环境下,如果获取 EventChannel 失败,控制台会输出警告信息
  4. 通过 on 注册的监听器会在组件卸载时自动清理,无需手动 off
  5. 如果需要手动移除某个监听器,可以使用 off 方法
  6. createEventChannelActions 是纯函数,不会自动清理监听器。如需自动清理,请使用 useEventChannel

基于 MIT 许可发布