Quasar CLI with Vite - @quasar/app-vite
BEX的类型

如前所述,Quasar可以处理浏览器扩展所在的各种位置,即“新建的选项卡”、“网页”、“开发工具选项”或“弹出窗口”。 您不需要每个位置的单独的Quasar应用程序。 您可以使用router进行一些便捷的工作。

新建的选项卡

这是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", // Options Page
  "browser_action": {
    "default_popup": "www/index.html#/popup" // Popup Page
  },
  "devtools_page": "www/index.html#/devtools", // Dev Tools
}

manifest v3

{
  "manifest_version": 3,

  "action": {
    "default_popup": "www/index.html#/popup" // Popup Page
  },
  "options_page": "www/index.html#/options", // Options Page
  "devtools_page": "www/index.html#/devtools", // Dev Tools
}

网页

这才是真正的力量所在。通过一点点独创性,我们可以将Quasar应用程序注入到网页中并将其用作覆盖,从而使我们的Quasar应用程序看起来像是页面体验的一部分。

以下是如何实现此目标的简要概述:

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

这里的想法是创建一个IFrame并将我们的Quasar应用添加到其中,然后将其注入到页面中。

鉴于我们的Quasar应用程序可能需要占用窗口的整个高度(从而停止与基础页面的任何交互),因此我们有一个事件来处理设置IFrame的高度。 默认情况下,IFrame的高度刚好足以允许Quasar工具栏显示(进而允许与页面的其余部分进行交互)。

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

// Hooks added here have a bridge allowing communication between the BEX Content Script and the Quasar Application.
// More info: https://quasar.dev/quasar-cli/developing-browser-extensions/content-hooks
import { bexContent } from 'quasar/wrappers'

const
  iFrame = document.createElement('iframe'),
  defaultFrameHeight = '62px'

/**
 * Set the height of our iFrame housing our BEX
 * @param height
 */
const setIFrameHeight = height => {
  iFrame.height = height
}

/**
 * Reset the iFrame to its default height e.g The height of the top bar.
 */
const resetIFrameHeight = () => {
  setIFrameHeight(defaultFrameHeight)
}

/**
 * The code below will get everything going. Initialize the iFrame with defaults and add it to the page.
 * @type {string}
 */
iFrame.id = 'bex-app-iframe'
iFrame.width = '100%'
resetIFrameHeight()

// Assign some styling so it looks seamless
Object.assign(iFrame.style, {
  position: 'fixed',
  top: '0',
  right: '0',
  bottom: '0',
  left: '0',
  border: '0',
  zIndex: '9999999', // Make sure it's on top
  overflow: 'visible'
})

;(function () {
  // When the page loads, insert our browser extension app.
  iFrame.src = chrome.runtime.getURL('www/index.html')
  document.body.prepend(iFrame)
})()

export default bexContent((bridge) => {
  /**
   * When the drawer is toggled set the iFrame height to take the whole page.
   * Reset when the drawer is closed.
   */
  bridge.on('wb.drawer.toggle', ({ data, respond }) => {
    if (data.open) {
      setIFrameHeight('100%')
    } else {
      resetIFrameHeight()
    }
    respond()
  })
})

我们可以在任何时候从我们的Quasar App中调用这个事件,我们知道我们正在打开滑动菜单,从而改变IFrame的高度,让整个滑动菜单可见。

  • src-bex/assets/content.css

在文档顶部添加页边距,以使Quasar工具栏不会与实际页面内容重叠。

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

然后在Quasar应用程序(/src)中,我们有一个函数可以切换drawer并将事件发送到内容脚本,告诉它调整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 // So it knows to make it bigger / smaller
    })

    // Only set this once the promise has resolved so we can see the entire slide animation.
    drawerIsOpen.value = !drawerIsOpen.value
  }

  return { drawerToggled }
}

现在,您已经在网页中运行了Quasar应用程序。 您现在可以通过Quasar应用触发其他事件, 其中内容脚本可以侦听基础页面并与之交互。

WARNING

一定要检查你的清单文件,特别是对my-content-script.js的引用。请注意,您可以有多个内容脚本。每当您创建一个新的脚本时,您需要在清单文件中引用它。