一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情。
前言
谷歌插件是一个使用html、js、css等前端技术开发,用来增强浏览器功能的插件,程序员日常可能会使用到的插件有HackBar
、Vue.js devtools
。借助谷歌插件,我们可以很容易地做出自己的“定制版”网页和“定制版”浏览器。
清明假期,疫情居家,我在家花了一天时间,基于vue3.x+ts开发了一款掘金一键三连的谷歌插件,可以实现对掘金文章的一键点赞、收藏和关注作者。插件的源码地址在这里~
通过本篇文章,你可以学到如何使用vue3.x+ts开发谷歌插件的页面(其实和普通业务开发一样),了解到一些谷歌插件开发的小知识。
开始
先来看下交互效果:
梳理出以下几个交互功能点:
- 点击插件图标,可以控制侧边栏的收起或展开;
- 侧边栏的switch按钮用来控制插件是否启用;
- 用户可以根据自己的喜好选择触发点赞、收藏、关注三种行为(默认一键三连,点赞不可取消触发);
- 当插件启用后,进入掘金文章进行点赞,即可实现一键三连效果。
- 插件的数据状态保存下来,刷新页面不丢失
功能明确之后,我们就可以开始搞设计啦~
谷歌插件要求目录中必须有一个manifest.json
,我们可以在其中配置一个background.js
用来监听用户点击插件图标、监听用户新建标签页等操作,background.js
会一直常驻在后台运行。
然后我们再配置一个content.js
,content.js
可以与网页共享DOM,操作DOM,但是不共享网页的js,我们可以通过往页面注入iframe实现侧边栏开发,注入js实现触发一键三连的js逻辑。
开工
梳理好功能点,做好方案设计之后,就可以开工编码了,项目的结构如下:
侧边栏内容就是一个表单,虽然很简单,但是我使用了vue3.x
+vite2.x
+NaiveUI
的主流技术栈(牛刀小试~)。
我会通过watch表单的值变化,然后将值变化消息通信给其它部分
侧边栏主要的逻辑如下:
export const useAppOn = () => {
const isAppOn = ref(false)
watch(isAppOn, newVal => {
const params = {
from: iframePart,
to: backgroundPart,
key: appOnKey,
value: newVal
}
chrome.runtime?.sendMessage(chrome.runtime.id, params)
window.parent?.postMessage({
from: iframePart,
to: injectPart,
key: appOnKey,
value: newVal,
}, '*')
chrome.storage?.local.set({ [appOnKey]: newVal })
})
chrome.storage?.local.get([appOnKey], res => {
if (res[appOnKey]) {
isAppOn.value = !!res[appOnKey]
}
})
return {
isAppOn,
}
}
复制代码
background.js
的监听逻辑如下:
chrome.runtime.onMessage.addListener(({ from, to, key, value }) => {
if (from === iframePart && to === backgroundPart && key === appOnKey) {
if (value === true) {
// balabala
} else {
// yy
}
}
})
复制代码
inject-page.js
的监听逻辑如下:
window.addEventListener('message', ({ data: { from, to, key, value, initData } }) => {
if (from === contentPart && to === injectPart && initData) {
// 初始化数据
} else if (from === iframePart && to === injectPart && key === appOnKey) {
// 启动或停止插件
} else if (from === iframePart && to === injectPart && key === checkItemsKey) {
// ......
}
}, false)
复制代码
总结就是各个部分的数据通信都是通过chrome.runtime.sendMessage
或者window.parent.postMessage
实现,
注入的js可以拿到数据之后,就能根据表单数据进行一键三连的行为模拟
const $agreeBtn = document.querySelector('.article-suspended-panel .panel-btn')
$agreeBtn?.addEventListener('click', () => {
if ($agreeBtn.className.includes('active') || !pageConfig.isAppOn) {
// 取消点赞行为就不往下走
// 未开启插件就不往下走
return
}
if (pageConfig.formData.follow) {
follow()
}
// ......
})
function follow() {
const $followBtn = document.querySelector<HTMLElement>('.article-area .follow-button')
if (!$followBtn.className.includes('followed')) {
$followBtn.click()
}
}
复制代码
代码写完后,打包时,需要将ts编译为js并且把图标啊、manifest.json
拷贝到dist目录下
import { exec } from 'child_process'
function main() {
exec('tsup')
exec('cp -r chrome/icons dist')
exec('cp -r chrome/manifest.json dist')
}
main()
复制代码
开发过程中遇到的问题、注意点
- 更新代码后,重新打包,需要在
chrome://extensions/
点击一下刷新按钮。
-
插件安装好后、或者更新后,需要重新刷新下网页,这样才能重新注入最新的js。
-
window.postMessage
发送对象数据时会报错,改成传递json字符串 -
谷歌插件需要指定
Manifest version
,目前我使用的是Manifest version 2
,不过v2已经不建议使用了,2023年将会被废弃,使用v3版本可以看这个迁移指南 -
插件各个部分的数据通信会比较麻烦,容易搞混乱,我们可以通过传from、to、key三个值进行判断,避免混乱。
-
inject-page.js
、iframe
要等到页面加载完成后再注入,不然一开始就注入的话,会获取不到点赞按钮等dom信息
相关链接
谷歌插件作为工具,如果使用得当,可以帮助我们定制功能,节省时间,提高效率。关于谷歌插件还有很多东西本文没讲到,本文只是以点切入面,如果读者阅读完本文后,觉得有所收获,请给作者一个小小的赞!!!一键三连,这次一定!!!