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
// 这里添加的钩子为 BEX 内容脚本和 Quasar 应用程序之间的通信搭建了一个桥梁。
// 更多信息: https://www.quasar-cn.cm/quasar-cli-vite/developing-browser-extensions/content-hooks
import { bexContent } from 'quasar/wrappers'
const
iFrame = document.createElement('iframe'),
defaultFrameHeight = '62px'
/**
* 设置 iframe 容纳 BEX 的高度
* @param height
*/
const setIFrameHeight = height => {
iFrame.height = height
}
/**
* 将 iframe 重置为默认高度,例如顶部栏的高度。
*/
const 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)
})()
export default function (bridge) {
/**
* 切换抽屉时,将 iFrame 高度设置为占据整个页面。
* 当抽屉关闭时重置高度。
*/
bridge.on('wb.drawer.toggle', ({ data, respond }) => {
if (data.open) {
setIFrameHeight('100%')
} else {
resetIFrameHeight()
}
respond()
})
}
我们可以在任何时候从 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 应用程序触发其他事件,内容脚本可以侦听这些事件并与底层页面进行交互。
警告
一定要检查 manifest 文件,尤其是对 my-content-script.js
的引用。请注意,您可以拥有多个内容脚本。每当创建新的时,都需要在清单文件中引用它。