为什么捐赠
API 浏览器
联系站长
Quasar CLI with Webpack - @quasar/app-webpack
BEX 的类型

如前所述,Quasar 可以处理各种位置的浏览器插件,即新选项卡、网页、开发者工具,右键菜单选项或弹窗。不需要为每一种插件都提供一个单独的 Quasar 应用,使用路由器即可。

新选项卡

这是 BEX 默认的运行方式。点击浏览器中的 BEX 图标即可访问。Quasar 应用将在新的(空白)选项卡中运行。

开发者工具,右键菜单选项或弹窗

这些都遵循相同的模式,设置一个路由并配置 manifest.json 文件,以便在尝试打开其中一种类型的插件时显示该路由对应的界面。例如:

routes.js:

const routes = [
  { path: "/options", component: () => import("pages/OptionsPage.vue") },
  { path: "/popup", component: () => import("pages/PopupPage.vue") },
  { path: "/devtools", component: () => import("pages/DevToolsPage.vue") },
];

您可以使用下面的内容配置 manifest.json 文件,以便从该路由加载页面:

manifest v2

{
  "manifest_version": 2,

  "options_page": "www/index.html#/options", // 右键选项菜单
  "browser_action": {
    "default_popup": "www/index.html#/popup" // 弹窗
  },
  "devtools_page": "www/index.html#/devtools" // 开发者工具
}

manifest v3

{
  "manifest_version": 3,

  "action": {
    "default_popup": "www/index.html#/popup" // 弹窗
  },
  "options_page": "www/index.html#/options", // 右键选项菜单
  "devtools_page": "www/index.html#/devtools" // 开发者工具
}

案例分析:Web 页面

真正厉害的是,我们可以使用一些简单的技巧,将 Quasar 应用注入到页面中,使其成为页面的一部分。

下面是一个简单的示例:

  • src-bex/my-content-script.js

思路是创建一个 IFrame,并将我们的 Quasar 应用添加到其中,然后注入到网页中。

考虑到我们的 Quasar 应用可能会占据窗口的全部高度(从而阻挡与底层页面的任何交互),我们需要有一个事件来处理 IFrame 的高度设置。默认情况下,IFrame 高度刚好高到可以显示 Quasar 工具栏(进而允许与页面的其他部分交互)。

/src-bex/my-content-script.js

/**
 * Importing the file below initializes the content script.
 *
 * Warning:
 *   Do not remove the import statement below. It is required for the extension to work.
 *   If you don't need createBridge(), leave it as "import '#q-app/bex/content'".
 */
import { createBridge } from "#q-app/bex/content";

const bridge = createBridge({ debug: false });

/**
 * 切换抽屉时,将 iFrame 高度设置为占据整个页面。
 * 当抽屉关闭时重置高度。
 */
bridge.on("wb.drawer.toggle", ({ data, respond }) => {
  if (data.open) {
    setIFrameHeight("100%");
  } else {
    resetIFrameHeight();
  }
  respond();
});

const iFrame = document.createElement("iframe");
const defaultFrameHeight = "62px";

/**
 * 设置 iframe 容纳 BEX 的高度
 * @param height
 */
function setIFrameHeight(height) {
  iFrame.height = height;
}

/**
 * 将 iframe 重置为默认高度,例如顶部栏的高度。
 */
function resetIFrameHeight() {
  setIFrameHeight(defaultFrameHeight);
}

/**
 * 下面的代码将使一切顺利进行。用默认设置初始化 iframe,然后将其添加到页面上。
 * @type {string}
 */
iFrame.id = "bex-app-iframe";
iFrame.width = "100%";
resetIFrameHeight();

// 应用一些样式,使其看起来更像一个整体
Object.assign(iFrame.style, {
  position: "fixed",
  top: "0",
  right: "0",
  bottom: "0",
  left: "0",
  border: "0",
  zIndex: "9999999", // 确保它在最顶层
  overflow: "visible",
});
(function () {
  // 当页面加载时,插入我们的浏览器插件应用程序。
  iFrame.src = chrome.runtime.getURL("www/index.html");
  document.body.prepend(iFrame);
})();

我们可以在任何时候从 Quasar 应用程序调用此事件,因为我们知道正在打开抽屉,因此可以更改 IFrame 的高度,以使整个抽屉可见。

  • src-bex/assets/content.css

在文档的顶部添加一个边距,这样我们的 Quasar 工具栏就不会与实际的页面内容重叠。

.target-some-header-class {
  margin-top: 62px;
}
  • Quasar App (/src)

然后在我们的 Quasar 应用程序 (/src)中,我们有一个函数来切换抽屉,并向内容脚本发送一个事件,告诉它调整 IFrame 的大小,从而使我们的整个应用程序可见:

<q-drawer :model-value="drawerIsOpen" @update:model-value="drawerToggled"> Some Content </q-drawer>
import { useQuasar } from 'quasar'
import { ref } from 'vue'

setup () {
  const $q = useQuasar()
  const drawerIsOpen = ref(true)

  async function drawerToggled () {
    await $q.bex.send('wb.drawer.toggle', {
      open: drawerIsOpen.value // 所以它知道要变得更大 / 更小
    })

    // 只有在 Promise 解决后才设置此选项,这样我们才能看到整个滑动动画。
    drawerIsOpen.value = !drawerIsOpen.value
  }

  return { drawerToggled }
}

现在你有一个 Quasar 应用程序在网页上运行。您可以从 Quasar 应用程序触发其他事件,内容脚本可以侦听这些事件并与底层页面进行交互。

WARNING

请务必检查您的 manifest.json 文件,特别是关于 my-content-script.js 的引用。请注意,您可以有多个内容脚本。每当您创建一个新的内容脚本时,都需要在 manifest 文件中引用它。对于 /src-bex/assets 文件夹中创建的任何 css 文件也是如此。


/src-bex/manifest.json

"content_scripts": [
  {
    "matches": [ "<all_urls>" ],
    "css": [ "assets/content.css" ],
    "js": [ "my-content-script.js" ]
  }
]