Skip to content

在其他页面中使用消息管理 ​

typescript
//  background.ts
import { extId } from "@/const";
import { InjectMessageType, BackgroundMessageType } from "@/messageType";

//  注意⚠️这里引用的文件位置为 @webextkits/messages-center/background
import { MessageInstance } from "@webextkits/messages-center/background";

const mc = new MessageInstance<InjectMessageType, BackgroundMessageType>(
  //  为了不与其他扩展的消息冲突,这里需要传入唯一标识符,也就是你扩展的别名
  extId,
  //  是否开启 debug,默认关闭。传入 true 后会在收到消息和返回消息时打印信息到控制台
  true
);

export function useMessages() {
  //  在这里你可以对某个消息进行监听处理
  mc.on("readUserName", async () => {
    const user = await getBucket("user");
    return user.name;
  });

  mc.on("setUserName", (name: string) => {});
}
//  background.ts
import { extId } from "@/const";
import { InjectMessageType, BackgroundMessageType } from "@/messageType";

//  注意⚠️这里引用的文件位置为 @webextkits/messages-center/background
import { MessageInstance } from "@webextkits/messages-center/background";

const mc = new MessageInstance<InjectMessageType, BackgroundMessageType>(
  //  为了不与其他扩展的消息冲突,这里需要传入唯一标识符,也就是你扩展的别名
  extId,
  //  是否开启 debug,默认关闭。传入 true 后会在收到消息和返回消息时打印信息到控制台
  true
);

export function useMessages() {
  //  在这里你可以对某个消息进行监听处理
  mc.on("readUserName", async () => {
    const user = await getBucket("user");
    return user.name;
  });

  mc.on("setUserName", (name: string) => {});
}

在 options 页面监听消息 ​

只要是能执行 runtime.onMessageExternal.addListener 的页面,你都可以通过上面这种方式监听 injectScript 传递过来的消息,比如在 options、popup 和 sidepanel 页面

typescript
// options/app.tsx

import { extId } from "@/const";
import { InjectMessageType, BackgroundMessageType } from "@/messageType";

const mc = new MessageInstance<InjectMessageType, BackgroundMessageType>(
  extId,
  true
);

export function useMessages() {
  //  在这里你可以对某个消息进行监听处理
  mc.on("readUserName", async () => {
    const user = await getBucket("user");
    return user.name;
  });

  mc.on("setUserName", (name: string) => {});
}
// options/app.tsx

import { extId } from "@/const";
import { InjectMessageType, BackgroundMessageType } from "@/messageType";

const mc = new MessageInstance<InjectMessageType, BackgroundMessageType>(
  extId,
  true
);

export function useMessages() {
  //  在这里你可以对某个消息进行监听处理
  mc.on("readUserName", async () => {
    const user = await getBucket("user");
    return user.name;
  });

  mc.on("setUserName", (name: string) => {});
}

注意 ​

如果你在多个地方对同一个消息进行了监听处理,只有一个监听函数会执行,这是 Chrome 的限制

If multiple pages are listening for onMessage events, only the first to call sendResponse() for a particular event will succeed in sending the response. All other responses to that event will be ignored.

如何获取 tabId ​

在监听到事件之后,我们可能要知道 sender 到底是谁,获取对应的 tabId 进行操作。我们可以通过 this 指向来获取 sender 的数据

typescript
mc.on("setUserName", function (name: string) {
  //  在此处获取 this.sender
  console.log(this.sender);

  //  从 sender 中获取 tabId(如需仅给当前来源页发送消息)
  const tabId = this.sender?.tab?.id;
  if (tabId) {
    //  使用 sendByTabId 仅向当前来源页面发送确认/反馈消息
    mc.sendByTabId(tabId, "setUserNameAck", name);
  }
});
mc.on("setUserName", function (name: string) {
  //  在此处获取 this.sender
  console.log(this.sender);

  //  从 sender 中获取 tabId(如需仅给当前来源页发送消息)
  const tabId = this.sender?.tab?.id;
  if (tabId) {
    //  使用 sendByTabId 仅向当前来源页面发送确认/反馈消息
    mc.sendByTabId(tabId, "setUserNameAck", name);
  }
});

按指定 tabId 发送消息 ​

当你只想向某一个特定页面发送消息时,可以使用 sendByTabId(tabId, action, ...payload):

typescript
// 已知 tabId 时,直接向该页面发送
await mc.sendByTabId(123, "readUserName");
// 已知 tabId 时,直接向该页面发送
await mc.sendByTabId(123, "readUserName");

你也可以接收页面返回的结果

typescript
// 已知 tabId 时,直接向该页面发送
mc.sendByTabId(123, "readUserName").then(console.log);
// 已知 tabId 时,直接向该页面发送
mc.sendByTabId(123, "readUserName").then(console.log);

向所有已连接页面广播 ​

如果你希望向所有已建立连接(connect)的页面发送同一条消息,使用 send(action, ...payload):

typescript
await mc.send("readUserName");
await mc.send("readUserName");

向所有已连接的页面广播并处理返回结果 ​

每个页面返回的结果都会调用第二个 callback 方法,并且接收: result:返回结果 sender:这个 tab 的信息

typescript
mc.sendWithCallback(
  "eventName",
  (result, sender) => {
    console.log(result, sender);
  },
  args
);
mc.sendWithCallback(
  "eventName",
  (result, sender) => {
    console.log(result, sender);
  },
  args
);

Powered by Vitepress