使用Vue3+Element Plus开发Chrome插件
使用Vue3+Element Plus开发Chrome插件
- 引言
- 初始Vue项目的创建
- Element-Plus组件的安装及导入
- 其他文件配置
- .eslintrc.js文件
- vue.config.js文件
- package.json
- src/文件夹
- assets/
- background/main.js
- content/components/app.vue文件
- content/main.js文件
- plugins/inject.js
- plugins/manifest.json文件
- popup/components/app.vue文件
- popup/index.html
- 成果检验
- 热更新设置
- 2022-8-17使用的vue环境
引言
本人Vue3小白一枚,目前正在研究基于Vue3的Chrome浏览器插件的使用,经过不断尝试和整合各路大佬方法,现将自己尝试有效的项目框架搭建流程进行总结。在此非常感谢大佬们的分享。
本文主要参考文章——15000字大章带你一步一步使用Vue3开发chrome浏览器插件
初始Vue项目的创建
- 控制台中输入
vue create XXX
创建新的vue工程项目 - 在创建工程过程中选择Manually select features手动配置模块
- 选中babel、linter、router后进行下一步,其中router项目若无需求可不选
- 对于vue.js选择3.x版本
- Router模式选择history
- 选择ESLint with error prevention only,不选其他的,不然代码规范对后续开发产生很多麻烦
- 随后选择Lint on save,如果有Git也可选择下面那项
- 选择In dedicated config files将eslint、babel等文件分别单独存放
- 完成初始Vue项目的创建
Element-Plus组件的安装及导入
- 控制台输入
npm install element-plus --save
向Vue项目安装element-plus组件 - 项目结构可参考大佬的文章所给出的结构,我的项目最终产出的目录结构为:
├── dist
│ ├── assets
│ │ ├── images
│ │ │ ├── icon128.png
│ │ │ ├── icon16.png
│ │ │ └── icon48.png
│ │ └── logo.png
│ ├── js
│ │ ├── background.js
│ │ ├── chunk-vendors.js
│ │ ├── content.js
│ │ ├── inject.js
│ │ └── popup.js
│ ├── manifest.json
│ └── popup.html
├── src
│ ├── assets
│ │ ├── images
│ │ │ ├── icon128.png
│ │ │ ├── icon16.png
│ │ │ └── icon48.png
│ │ └── logo.png
│ ├── background
│ │ └── main.js
│ ├── content
│ │ ├── components
│ │ │ └── app.vue
│ │ └── main.js
│ ├── plugins
│ │ ├── inject.js
│ │ └── manifest.json
│ ├── popup
│ │ ├── components
│ │ │ └── app.vue
│ │ ├── index.html
│ │ └── main.js
│ ├── router
│ │ └── index.js
│ └── utils
│ └── hotReload.js
├── .browserslistrc
├── .eslintrc.js
├── .gitignore
├── babel.config.js
├── jsconfig.json
├── package-lock.json
├── package.json
├── README.md
└── vue.config.js
- 其中dist文件夹为执行
npm run build
指令后生成的,其他均应在执行npm run build
前准备就绪 - (如果开发的插件不涉及路由等操作,则删除src文件夹下的router/index.js文件夹及文件)
- 在
src/popup/main.js
中添加element-plus插件,代码如下:
import { createApp } from 'vue'
import App from './components/app.vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import zhCn from 'element-plus/es/locale/lang/zh-cn'const app = createApp(App)
app.use(ElementPlus, {locale: zhCn})
app.mount('#app')
- 至此,项目的创建和element-plus组件的导入完成
其他文件配置
.eslintrc.js文件
- 主要是在globals中添加
chrome: true
从而让chrome属性在全局的.js文件中为可用状态 - 复制以下内容到eslintrc.js文件中
module.exports = {root: true,globals: {chrome: true,},env: {node: true},'extends': ['plugin:vue/vue3-essential','eslint:recommended'],parserOptions: {parser: '@babel/eslint-parser'},rules: {'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off','no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'}
}
vue.config.js文件
- vue.config.js作为项目配置文件,对打包生成的dist文件夹以及src文件夹下的各文件起到关键作用
- 复制以下代码到vue.config.js文件中
const CopyWebpackPlugin = require("copy-webpack-plugin");
const path = require("path");// 复制文件到指定目录
const copyFiles = [{from: path.resolve("src/plugins/manifest.json"),to: `${path.resolve("dist")}/manifest.json`},{from: path.resolve("src/assets"),to: path.resolve("dist/assets")},{from: path.resolve("src/plugins/inject.js"),to: path.resolve("dist/js")}
];// 复制插件
const plugins = [new CopyWebpackPlugin({patterns: copyFiles})
];// 页面文件
const pages = {};
// 配置 popup.html 页面
const chromeName = ["popup"];chromeName.forEach(name => {pages[name] = {entry: `src/${name}/main.js`,template: `src/${name}/index.html`,filename: `${name}.html`};
});module.exports = {pages,productionSourceMap: false,// 配置 content.js background.jsconfigureWebpack: {entry: {content: "./src/content/main.js",background: "./src/background/main.js"},output: {filename: "js/[name].js"},plugins},// 配置 content.csscss: {extract: {filename: "css/[name].css"}},chainWebpack: config => {if (process.env.NODE_ENV === 'production') {config.output.filename('js/[name].js').end()config.output.chunkFilename('js/[name].js').end()}}
}
package.json
- 在 "scripts"字段中添加 “watch”: “vue-cli-service build --watch”,来增加NPM脚本中对插件的热监控功能
"scripts": {"watch": "vue-cli-service build --watch","serve": "vue-cli-service serve","build": "vue-cli-service build","lint": "vue-cli-service lint"},
src/文件夹
- src文件夹下主要针对manifest.json文件、popup中的文件、content中的文件进行更改
assets/
- assets文件中用于存放图标,注意images文件夹内的三张图片要是同一个图片的不同的名称,例如:
background/main.js
- background作为Chrome插件的后台,随着浏览器的启动而启动,可将全局性的、一直运行的功能放在此处
- 考虑到仅仅做一个demo,此处此处打印一串字作为测试,将以下内容复制到main.js中
console.log('this is background')
content/components/app.vue文件
- 添加以下内容到app.vue文件作为植入到浏览器中的HTML文件(不植入无法获取网页中的DOM)
- 注意:此时的.vue文件尚未具有注入HTML中的能力
<template><div class="head">this is the content</div>
</template><script setup>
</script><style scoped>
.head{color: red;position: fixed;z-index: 100001;right: 10px;bottom: 10px;
}
</style>
content/main.js文件
- 添加以下内容到main.js文件中,在浏览器当前Tab中创建一个< div >标签并将app.vue文件加载到标签中以完成HTML的植入的操作
- 当app.vue成功植入到HTML中时,我们便可以通过chrome自带的功能猥琐欲为了
import { createApp } from 'vue'
import app from './components/app.vue'
joinContent(app)
injectJsInsert()
function joinContent (element) {const div = document.createElement('div')div.id = 'joinContentApp'document.body.appendChild(div)console.log(div)createApp(element).mount('#joinContentApp')
}
//chrome的API接口,用于传输或监听数据信号
chrome.extension.onRequest.addListener( function (request) {if (request.popAction == "Test") {console.log("test")}}
);
function injectJsInsert () {document.addEventListener('readystatechange', () => {const injectPath = 'js/inject.js'const script = document.createElement('script')script.setAttribute('type', 'text/javascript')script.src = chrome.extension.getURL(injectPath)document.body.appendChild(script)})
}
plugins/inject.js
- inject.js文件主要负责分析网页的DOM,拿到大图资源链接,并翻页,直到获取足够数量的图片
- 可以在此文件内输入以下内容,最终结果可在浏览器窗口的控制台中打印出来
console.log('this is inject')
plugins/manifest.json文件
- manifest.json文件的重要性再此不多做赘述了,文件中各个字段的意义和功能请见其他大佬的博客——Chrome插件manifest.json文件详解
- 复制以下内容到manifest.json中以完成Chrome插件的配置
{"manifest_version": 2,"name": "test","description": "Vue3的Chrome插件","version": "1.0.0","browser_action": {"default_title": "plugin-base-vue3","default_icon": "assets/images/icon48.png","default_popup": "popup.html"},"permissions": [],"background": {"scripts": ["js/chunk-vendors.js", "js/background.js"]},"icons": {"16": "assets/images/icon16.png","48": "assets/images/icon48.png","128": "assets/images/icon128.png"},"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'","content_scripts": [{"matches": ["http://*/*", "https://*/*"],"css": ["css/content.css"],"js": ["js/chunk-vendors.js", "js/content.js"],"run_at": "document_idle"}],"web_accessible_resources": ["js/inject.js"]
}
popup/components/app.vue文件
- 添加以下内容到app.vue文件中作为浏览器插件的前端显示窗口
<template><div class="wrapper"><el-button type="danger" @click="test">测试按钮</el-button></div>
</template>
<script setup>
const test = () => {chrome.tabs.getSelected(null, function(tab){chrome.tabs.sendRequest(tab.id, { popAction: "Test"});});
}
</script>
<style scoped>
.wrapper{width: 100px;height: 100px;background-color: aquamarine;
}
</style>
popup/index.html
- index.html文件作为.vue文件的载体,其内容使用新建项目时的初始内容即可
<!DOCTYPE html>
<html lang="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>test</title></head><body><noscript><strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body>
</html>
- 上述文件内容填写完成后在控制台执行
npm run build
指令以获得dist文件,使用Chrome加载dist文件夹以加载插件
成果检验
- 在加载插件的窗口中,点击查看视图旁的背景页可以看到来自background/main.js文件的打印内容
- 打开任意一个页面可以看到右下角出现了this is the content-script字样,这说明我们的content里的app.vue文件已经成功植入到网页的html文件中了
- 打开插件,出现了带有Element-plus控件元素的按钮,说明Element已经成功引入
- 打开控制台(F12)可以看到植入到html页面中的< div >元素被打印了出来,同时来自plugins/inject.js的内容也被打印了出来
- 点击插件中的按钮在控制台中出现了test字样,这说明content中的js文件已经接收到了来自popup中js传来的信息(由于.vue内带有script的编写区域,因此chrome的数据传输功能可直接在.vue文件中进行)
- 恭喜你!你已经成功搭建了基于Vue3+Element-plus的Chrome框架
热更新设置
- 如果不采用热更新,开发过程中将会不断经历"更改->打包->加载->再更改"的痛苦历程,为了提高开发效率,在utils/hotReload.js文件中添加以下内容:
// 加载文件const filesInDirectory = dir =>new Promise(resolve =>dir.createReader().readEntries(entries => {Promise.all(entries.filter(e => e.name[0] !== '.').map(e =>e.isDirectory ? filesInDirectory(e) : new Promise(resolve => e.file(resolve)))).then(files => [].concat(...files)).then(resolve);}));// 遍历插件目录,读取文件信息,组合文件名称和修改时间成数据
const timestampForFilesInDirectory = dir =>filesInDirectory(dir).then(files =>files.map(f => f.name + f.lastModifiedDate).join());// 刷新当前活动页
const reload = () => {window.chrome.tabs.query({active: true,currentWindow: true},tabs => {// NB: see https://github.com/xpl/crx-hotreload/issues/5if (tabs[0]) {window.chrome.tabs.reload(tabs[0].id);}// 强制刷新页面window.chrome.runtime.reload();});
};// 观察文件改动
const watchChanges = (dir, lastTimestamp) => {timestampForFilesInDirectory(dir).then(timestamp => {// 文件没有改动则循环监听watchChanges方法if (!lastTimestamp || lastTimestamp === timestamp) {setTimeout(() => watchChanges(dir, timestamp), 1000); // retry after 1s} else {// 强制刷新页面reload();}});
};const hotReload = () => {window.chrome.management.getSelf(self => {if (self.installType === 'development') {// 获取插件目录,监听文件变化window.chrome.runtime.getPackageDirectoryEntry(dir => watchChanges(dir));}});
};export default hotReload;
- 同时修改background/main.js为:
import hotReload from '@/utils/hotReload'
hotReload()
console.log('this is background')
- 在package.json中的
scripts
字段中添加"watch": "vue-cli-service build --watch",
来向NPM脚本中添加热更新快捷操作
2022-8-17使用的vue环境
- 本文创建于2022-8-17日,采用的package.json为:
{"name": "plugin","version": "0.1.0","private": true,"scripts": {"watch": "vue-cli-service build --watch","serve": "vue-cli-service serve","build": "vue-cli-service build","lint": "vue-cli-service lint"},"dependencies": {"core-js": "^3.8.3","element-plus": "^2.2.13","vue": "^3.2.13","vue-router": "^4.0.3"},"devDependencies": {"@babel/core": "^7.12.16","@babel/eslint-parser": "^7.12.16","@vue/cli-plugin-babel": "~5.0.0","@vue/cli-plugin-eslint": "~5.0.0","@vue/cli-plugin-router": "~5.0.0","@vue/cli-service": "~5.0.0","eslint": "^7.32.0","eslint-plugin-vue": "^8.0.3","less": "^4.1.3","less-loader": "^11.0.0"}
}
- 通常来说,即使不采用本文的各模块版本,按照本文提供的方法一步一步执行也可以创建出Chrome插件的框架
- 本文所讲述内容,作者从项目创建开始一步一步执行,亲测有效,所涉及各项功能均无异常
使用Vue3+Element Plus开发Chrome插件相关推荐
- 一文教会你如何用Vue开发Chrome插件
前言 作为一个常年的B端前端开发者来说,千篇一律的业务开发有着些许的枯燥无味.在联调过程中,会经常发现后端在部署服务,然后又不知什么时候部署好,由于公司的部署系统查看系统部署状态入口较深,所以闲暇之余 ...
- 开发chrome 插件, background.js中 console log 看不到解决方法
开发chrome 插件, background.js中 console log 看不到解决方法 参考文章: (1)开发chrome 插件, background.js中 console log 看不到 ...
- blazor wasm开发chrome插件
用blazor(Wasm)开发了一个chrome插件感觉效率挺高的,分享给大家 先简单介绍下WebAssembly的原理: "WebAssembly是一种用于基于堆栈的虚拟机的二进制指令格式 ...
- 利用Vue 脚手架 开发chrome 插件,太方便了
前言 一个 Chrome 插件,核心就是 manifest.json 文件,manifest.json 下的属性 content_scripts 指定inject的脚本列表 js,css [ inje ...
- 使用 React.js 开发 Chrome 插件
(点击上方公众号,可快速关注) 来源:UncleChen unclechen.github.io/2017/06/16/使用ReactJS开发Chrome插件/ 一.背景 相信看到这篇文章的人应该都用 ...
- 记录--使用Vue开发Chrome插件
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 环境搭建 Vue Web-Extension - A Web-Extension preset for VueJS (vue-web-ex ...
- 开发chrome插件(扩展)
官方文档 https://developer.chrome.com/extensions/getstarted.html [干货]Chrome插件(扩展)开发全攻略 http://blog.haoji ...
- React开发chrome插件系列教程之chrome插件基本介绍
文章目录 chrome插件能干什么 chrome插件的版本 chrome插件的浏览器支持 chrome插件的功能组成 manifest.json popup content script backgr ...
- 试着开发chrome插件
我的第一个chrome插件,是app形式的 代码如下 创建一个文件: 1.manifest.json 1 { 2 "version": "1.0", 3 &qu ...
最新文章
- 网民关注iPhone、Google、微软和安全
- sicily 1068. Euro Efficiency
- 怎么查看mysql正在运行的语句_MySQL如何查询当前正在运行的SQL语句
- 与素数有关的一些性质及证明(一)
- Struts2之命名空间与Action的三种创建方式
- HashMap中,比较key是否相等为什么要重写equal() 和hashCode()这两个方法?
- iOS:const的使用
- spring常见用法之安全模块(注册登录模块)
- eclipse 图形界面设计技巧——JLabel
- 苹果Mac电脑缓存如何清理?
- 【转】精彩RSS源推荐
- 蓝桥杯练习题之数列特征
- 关于图灵机的妙文(3)——图灵机杂思(rev#2)(刘未鹏)
- kvaser leaf light v2 安装 UBUNTU
- js几行代码搞定html转图片制作海报,html2canvas应用实例
- 【推荐+转摘】如何又快又好的做出一份优质PPT
- Unity3d实现双人网络坦克大战
- 带你认识不一样的常春藤之一的普林斯顿大学
- 程序员应该如何读好书?
- Java中,通过synchronizedXxx()将线程不安全的集合转换成线程安全的集合
热门文章
- Linux下系统恢复
- 最近用到ListView需要几人人物,于是整理了下以前看的玄幻小说人名,时间不够,只整理了几本,凑合用着 1》诛仙
- 【Net】全球十大搜索引擎,你听过几个?
- 【模拟 简易银行系统~python】
- 函数自变量与因变量的关系
- 饥荒机器人怎么解锁_《饥荒》全人物解锁属性及技能详解 全人物介绍
- 病毒无孔不入:电邮一打开病毒自然来(转)
- DHU Matlab Experiment【6】作业记录_第七章
- js添加多marker 高德地图_web开发如何使用高德地图API(四)通过AMap.Marker自定义标点...
- h5 java实现微信分享_WebApp实现微信分享功能